hdu 2089 -不要62(数位 dp)

来源:互联网 发布:java ssl 双向认证 编辑:程序博客网 时间:2024/05/13 23:58

题目链接:点击打开链接

 更加具体的介绍可以参考:http://wenku.baidu.com/link?url=4w0ZDDhVubkEY87akx45gShFIpXmoZ1QLkq38TEi8c3x36R8SVpJ0aEuSkTmy6mySmaOGkE5oW6qMNj0Comtanbe_WERHx1V1VqQCYxn_2G

思路:基础的数位dp入门题,预处理+递推

/*************************************************************************    > File Name: 2089.cpp    > Author: Clannad    > Mail: 821199012@qq.com    > Created Time: Sun 17 July 2016 03:02:36 PM************************************************************************/#include <iostream>#include <cstdio>#include <vector>#include <map>#include <set>#include <queue>#include <stack>#include <algorithm>#include <sstream>#include <cmath>#include <cstdlib>#include <cstring>#include<string>#include <ctime>#define e 2.7182818284590452354#define pi acos(-1)using  namespace std;typedef  long  long  ll;const int inf=0x3f3f3f3f;const int maxn=100100;int dp[10][10];//dp[i,j]代表开头是j的i位数中不含"62"或"4"的数有几个//首先预处理数组dpvoid init(){    memset(dp,0,sizeof(dp));    dp[0][0]=1;    for(int i=1 ; i<=7 ; i++){        for(int  j=0 ; j<10 ; j++){//枚举第i位可能出现的数            for(int  k=0  ; k<10 ; k++){//枚举第i-1位可能出现的数                if(j!=4&&!(j==6&&k==2))                    dp[i][j]+=dp[i-1][k];            }        }    }}//然后统计区间[0,n)//digit[i] 代表 n 从右到左第i位是多少,len是n有几位。//如 n = 58 digit[1] = 8 digit[2] = 5int  solve(int n){    init();    int  digit[10],len=0;    while(n>0){        digit[++len]=n%10;        n/=10;    }    digit[len+1]=0;    int  ans=0;    for(int i=len ; i>=1 ; i--){//枚举哪一位<n的对应位        for(int  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))  //已经出现4或62            break;    }//例如5327,计算顺序就是0000~4999,5000~5299,5300~5319,5320~5326,万一高位出现4,62,就直接退出循环    return ans;}int main(){    std::ios::sync_with_stdio(false);    std::cin.tie(0);//    #ifndef ONLINE_JUDGE//        freopen("in.txt", "r", stdin);//    #endif    int l,r;    while(cin>>l>>r){        if(l+r==0)break;        else{            cout<<solve(r+1)-solve(l)<<endl;            //因为solve函数中并没有考虑n是不是不幸数的情况,所以r+1只算了1~r,            //而l只算了1~l-1,这两者相减才是正确答案        }    }    return 0;}


0 0
原创粉丝点击