zoukankan      html  css  js  c++  java
  • hdu 3555 Bomb(数位dp)

    题意:求1到n有多少个数中含有49,1<=n<=2^63-1(2^32是10位,2^64约20位)

    思路:数位dp

    dp[i][0],长度为i,不含有49的个数
    dp[i][1],长度为i,不含有49,最高位为9的个数
    dp[i][2],长度为i,含有49的个数

    状态转移方程:

    dp[i][0]=10*dp[i-1][0]-dp[i-1][1];//不含49的前面加0~9,减掉9前面加4
    dp[i][1]=dp[i-1][0];//不含49的前面加9
    dp[i][2]=10*dp[i-1][2]+dp[i-1][1];//含49的前面加0~9,加上9前面加4

    求解:从最高位开始遍历,每一位求的都是  前缀+小于当前位  的符合条件的个数。

    1.首先加上当前位置之后包含49的个数,因为当前为可以填0~bit[i]-1,所以乘以bit[i],ans+=dp[i-1][2]*bit[i];//注意这个位置,求的是前缀+当前位置
    2.前面的前缀出现49了,ans+=dp[i-1][0]*bit[i];//
    3.前缀没有出现49,并且当前位>4,ans+=dp[i-1][1];

    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    long long dp[25][3];
    /*
    dp[i][0],不含有49
    dp[i][1],不含有49,最高位为9
    dp[i][2],含有49
    */
    void init(){
        dp[0][0]=1;
        dp[0][1]=dp[0][2]=0;
        int i;
        for(i=1;i<25;++i){
            dp[i][0]=10*dp[i-1][0]-dp[i-1][1];//不含49的前面加0~9,减掉9前面加4
            dp[i][1]=dp[i-1][0];//不含49的前面加9
            dp[i][2]=10*dp[i-1][2]+dp[i-1][1];//含49的前面加0~9,加上9前面加4
        }
    }
    int bit[25];
    long long calc(long long n){
        int len=0,i;
        while(n){
            bit[++len]=n%10;
            n/=10;
        }
        bit[len+1]=0;
        bool flag=false;
        long long ans=0;
        for(i=len;i>=1;--i){
            ans+=dp[i-1][2]*bit[i];//注意这个位置,求的是前缀+当前位置
            if(flag)ans+=dp[i-1][0]*bit[i];
            else if(bit[i]>4)ans+=dp[i-1][1];
            if(bit[i+1]==4&&bit[i]==9)flag=true;
        }
        if(flag)++ans;//加上n本身
        return ans;
    }
    
    int main(){
        init();
        int t;
        long long n;
        scanf("%d",&t);
        while(t--){
            scanf("%lld",&n);
            printf("%I64d
    ",calc(n));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    18.5 推挽输出和开漏输出区别
    19.3 Table 1-2.S3C2440A 289-Pin FBGA Pin Assignments (Sheet 4 of 9) (Continued)
    19.2 MEMORY CONTROLLER
    19.1 PORT CONTROL DESCRIPTIONS
    17.2 SourceInsight批量注释
    17.3 删除没用的project
    17.1 添加汇编文件并可索引
    16.2 在SecureCRT编写C程序不高亮显示
    16.1 解决SecureCRT的Home+End+Del不好用使用方法
    15.1 打开文件时的提示(不是dos格式)去掉头文件
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4757122.html
Copyright © 2011-2022 走看看