zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    分页SQL取下一页
    取第10行到100行
    Flash Builder4.0新建Flex应用程序切换主题出错
    C++浮点数(float、double)类型数据比较、转换分析总结
    浮点数的大小比较
    052新题1
    一致读原理
    Redis配置文件解读
    Redis系列-远程连接redis并给redis加锁
    svn提交更新原则
  • 原文地址:https://www.cnblogs.com/sweat123/p/5113186.html
Copyright © 2011-2022 走看看