• hdu2089 数位dp


          第一次接触数位dp,对于这种题目,数字都是很大,直接遍历肯定超时,通过对每个位子上数字的遍历可以大大减小复杂度。

    dp[i][j]表示1到 i位的以j开头的数有几个满足条件的。这样理解一下,然后求出目标n的位数和各个位上的值,遍历即可。

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define INF 99999999
    #define ll __int64
    using namespace std;
    const int MAXN = 10;
    int dp[MAXN][MAXN];
    void init()
    {
        memset(dp,0,sizeof(dp));
        dp[0][0] = 1;
        int i,j,k;
        for(i=1; i<=9; i++){
            for(j=0; j<=9; j++){
                for(k=0; k<=9; k++){
                    if(j!=4 && !(j==6 && k==2)){
                        dp[i][j] += dp[i-1][k];
                    }
                }
            }
        }
    }
    int slove(int n)
    {
        int digit[10],i,j,k;
        memset(digit,0,sizeof(digit));
        int len = 0;
        int x = n;
        while(1){
            if(!x)break;
            digit[++len] = x%10;
            x/=10;
        }
        int ans = 0;
        for(i=len; i>=1; i--){
            for(j=0; j<digit[i]; j++){
                if(j!=4 && !(j==2 && digit[i+1]==6))
                    ans += dp[i][j];    
            }
            if(digit[i]==4 || (digit[i]==2 && digit[i+1]==6))//第i位是4 或者已经出现62了,不合法直接断开。
                break;
        }
        return ans;
    }
    int main()
    {
        int i,j,n,m;
        init();
        while(cin>>n>>m){
            if(!n && !m)break;
            cout<<slove(m+1)-slove(n)<<endl;//[0,m]-[0,n)
        }
        return 0;
    }
  • 相关阅读:
    自我介绍
    注册表代码
    圣杯布局
    css的颜色设置
    c语言:第二次作业,循环结构
    c语言:第一次作业,分支,顺序结构
    C语言博客作业03函数
    第零次作业
    用JSP判断输入是质数还是非质数
    用JSP完成输入整形,单精度浮点数,双精度浮点数
  • 原文地址:https://www.cnblogs.com/sweat123/p/5113186.html
Copyright © 2020-2023  润新知