zoukankan      html  css  js  c++  java
  • 数位dp——hdu2089不要62

    刚开始接触数位dp,看其他的博客和教程也不是很懂,不过学习就是一个循序渐进的过程嘛๑乛◡乛๑

    下面简单写写入门级的hdu2089不要62

    中途找到一个比较好的ppt,我觉得讲的还是很清楚的了->初探数位dp

    (下面的过程咋一看不明白可以把中间的过程打印出来,我是这样做的,感觉初学很见效)

    1、预处理

    dp[i][j]代表首位为j的i位数里符合条件(不含62和4)的数的个数

    提前都算出来,在下一步可以直接用(数组开销也不大,本题中[7][10]足够了)

    比如dp[3][0]代表的就是000~099之间符合条件的数,dp[3][1]代表100~199之间的数...

    2、计算

    统计区间[left,right]的个数可以看作[0,right]-[0,left)

    可以设想把一个数分成不同范围的数的集合并集

    比如321可以看作[0,99]+[100,199]+[200,299]+[0,9]+[10,19]+[0,1],即dp[3][0]+dp[3][1]+dp[3][2]+dp[2][0]+d[2][1]+dp[1][0]+dp[1][1]

    用digit[i]表示从右到左第i位上的数

    如果在循环的时候遇到4或者62则停止计算(循环是从高位到低位算的,4和62往后的低位都不用考虑了)

    动手做做想的更快些(•‾̑⌣‾̑•)✧˖°

    #include <iostream>
    using namespace std;
    int dp[10][10] = {0};
    void init()  
    {  
        int i,j,k;  
        for(i = 0; i <=9; ++i) dp[1][i] = 1;  
        dp[1][4] = 0;  
        for(i = 2; i <= 6; ++i)  
        {  
            for(j = 0; j <= 9; ++j)  
            {  
                if(j==4)continue;  
                for(k = 0; k <= 9; ++k)  
                {  
                    if(k!=4&&!(j==6&&k==2)) dp[i][j] += dp[i-1][k];  
                }  
            }  
        }  
    }  
    /* 
    void soutInit(){
        for(int i=0;i<=6;++i){
            for(int j=0;j<=9;++j){
                cout<<"dp["<<i<<"]["<<j<<"]="<<dp[i][j]<<endl;
            }
        }
    }*/ 
    int solve(int n)  
    {  
        int i,j,k,digit[10];  
        int len = 0,ans = 0;  
        while(n!=0)  
        {  
            digit[++len] = n%10;  
            n/=10;  
        }  
        digit[len+1] = 0;  
        for(i = len; i > 0; --i)  
        {  
            for(j = 0; j < digit[i]; ++j)  
            {  
                if(j==4 || (digit[i+1]==6 && j == 2))continue;  
                ans += dp[i][j];  
                //cout<<"dp["<<i<<"]["<<j<<"]"<<" ";
            }  
            if(digit[i]==4||(digit[i]==2&&digit[i+1]==6))break;  
        }  
        return ans;  
    }  
    
    int main() {
        init();
        //soutInit();
        int l,r;
        while(cin>>l>>r){
            if(l==0&&r==0){
                break;
            }
            cout<<solve(r+1)-solve(l)<<endl;
        }
        return 0;
    }

    最后皮一下:

    单说这道题的话,其实想过用字符串检测是否包含“62”或者“4”的,然后。。。TLE了(,,Ծ‸Ծ,,)

  • 相关阅读:
    js 中 undefined 和null 的区别
    【Gym103107E/黑龙江省赛16thE】Elastic Search(Trie树性质+ac自动机性质)
    不等概率抽卡的毕业期望次数
    博客园无法用IE进行登录
    Web项目开发小结
    各位看官,自己觉着喜欢的存到手机里面
    MVC控制器执行重定向
    吐了个槽o.o
    浏览器设置不缓存的方法
    关于A+B
  • 原文地址:https://www.cnblogs.com/zhaoGavin/p/8655936.html
Copyright © 2011-2022 走看看