HDU 3555含有49(数位dp)

题目地址:HDU 3555题意: 问(0, n]里面有几个数有'49'这个子串

#include <iostream>
#include <cstring>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <algorithm>
using namespace std;
#define Debug(x) cout << #x << " " << x <<endl
#define Memset(x, a) memset(x, a, sizeof(x))
const int INF = 0x3f3f3f3f;
typedef long long LL;
typedef pair<int, int> P;
#define FOR(i, a, b) for(int i = a;i < b; i++)
LL n;
LL f[31][2][2];
int digit[35];
LL z[35];
LL dfs(int len,int have, int s, int e){//模板;
    if(len == -1) return have;//结束
    if(!e && f[len][have][s] != -1) return f[len][have][s];//满足条件
    
    LL ans = 0;
    int u = e ? digit[len] : 9;//看有无限制
    for(int d = 0;d <= u; d++){
        if(s && d == 9){//含有49
            ans += dfs(len-1, 1, d == 4, e && d == u);
        }else{
            ans += dfs(len-1,have, d == 4 , e && d == u);
        }
    }
    return e ? ans : f[len][have][s] = ans;
}
LL solve(LL x){
    Memset(digit, 0);
    int len = 0;
    while(x){
        digit[len++] = x%10;
        x /= 10;
    }
    return dfs(len-1, 0, 0, 1);
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while(t--){
        cin >> n;
        Memset(f, -1);
        cout << solve(n) << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lanshan1111/article/details/81914633