• Bomb HDU


    Bomb HDU - 3555 (数位DP)

    The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "49", the power of the blast would add one point. 
    Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them? 

    InputThe first line of input consists of an integer T (1 <= T <= 10000), indicating the number of test cases. For each test case, there will be an integer N (1 <= N <= 2^63-1) as the description. 

    The input terminates by end of file marker. 
    OutputFor each test case, output an integer indicating the final points of the power.Sample Input

    3
    1
    50
    500

    Sample Output

    0
    1
    15
    
    
            
     

    Hint

    From 1 to 500, the numbers that include the sub-sequence "49" are "49","149","249","349","449","490","491","492","493","494","495","496","497","498","499",
    so the answer is 15.

    题意:求1-n之间有几个数带有49
    题解:一题数位DP,可以用记忆化搜索解决,感觉板子还是有点懂了,但不知道改了之后会不会了,具体的dfs的每一步的具体操作已经放在代码里了
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<sstream>
    #include<cmath>
    #include<stack>
    #include<cstdlib>
    #include <vector>
    #include<queue>
    using namespace std;
    
    using namespace std;
    #define ms(a,b) memset(a,b,sizeof(a))
    #define lson rt*2,l,(l+r)/2
    #define rson rt*2+1,(l+r)/2+1,r
    typedef unsigned long long ull;
    typedef long long ll;
    const int MAXN=1e4+5;
    const double EPS=1e-8;
    const int INF=0x3f3f3f3f;
    const int MOD = 1e9+7;
    
    #define ll long long
    #define llu unsigned long long
    #define INF 0x3f3f3f3f
    #define PI acos(-1.0)
    const int maxn =  1e5+5;
    const int  mod = 1e9+7;
    
    int bit[40];
    ll f[40][4];
    ll dp(int pos,int st,bool flag)
    {
        //pos为位,st为状态,st=0:没有49,st=1:前一位为4,st=2,表示49都已经出现过了
        //flag表示高位与原数是否相同
        if(pos == 0)
            return st == 2;
        if(flag && f[pos][st] != -1)
            return f[pos][st];
        ll ans = 0;
        int x;
        if(flag)
            x = 9;
        else
            x = bit[pos];
        //cout<<x<<endl;
        for(int i = 0;i <= x; i++)
        {
            if((st == 2) || (st == 1 && i == 9))    //如果上一位已经有49(st==2)或者上一位为4(st==1)当前位为9
                ans += dp(pos-1,2,flag || i<x);     //只能加上上一个状态,且上一个状态一定为已经有49了
            else if(i == 4)
                ans += dp(pos-1,1,flag || i<x);     //当前为4和前一位也为4的状态是一样的
            else                                    //维持st=0的状态
                ans += dp(pos-1,0,flag || i<x);
        }
        if(flag)
            f[pos][st] = ans;   //记忆化
        return ans;
    }
    
    ll calc(ll x)
    {
        int len = 0;
        while(x)
        {
            bit[++len] = x % 10;
            x /= 10;
        }
        //cout<<len<<endl;
        return dp(len,0,0);
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        memset(f,-1,sizeof f);
        while(t--)
        {
            ll n;
            scanf("%lld",&n);
            printf("%lld
    ",calc(n));
        }
    }
    
  • 相关阅读:
    [转]为什么阿里巴巴要禁用Executors创建线程池?
    支付宝的架构到底有多牛逼!
    [转] Java Agent使用详解
    Spring Boot必备技能之Starter自定义
    面试题:JVM 堆内存溢出后,其他线程是否可继续工作?
    Docker 容器化应用
    Python Click 学习笔记
    MySQL优化(7):其他注意事项
    MySQL优化(6):分表和读写分离
    MySQL优化(5):分区
  • 原文地址:https://www.cnblogs.com/smallhester/p/10324872.html
Copyright © 2020-2023  润新知