HDU 2089 不要62 数位DP .

来源:互联网 发布:淘宝新店有扶持吗 编辑:程序博客网 时间:2024/06/07 09:06

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2089

模板题 ,第一道数位DP的题目


#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>using namespace std;int d[10][2],a[10];int DFS(int pos,int pre,int state,bool limit){   //搜索到第几位| 前一位是什么| 状态,也即是前一位是不是6| 记录当前位最大多少if(pos==-1) return 1;int& ans=d[pos][state];if(!limit && ans!=-1) return ans;int up=limit? a[pos] : 9;int temp=0;for(int i=0;i<=up;i++){if((pre==6&&i==2)||i==4) continue;temp+=DFS(pos-1,i,i==6,limit&&i==a[pos]);}if(!limit) ans=temp;return temp;}int DP(int x){int pos=0;while(x){a[pos++]=x%10;x/=10;}return DFS(pos-1,-1,0,true);}int main(int argc, char const *argv[]){int n,m;while(cin>>n>>m,n+m){memset(d,-1,sizeof(d));cout<<DP(m)-DP(n-1)<<endl;}return 0;}


下面是递推的方法:

思路来自:http://blog.csdn.net/wangyuquanliuli/article/details/13761661

#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>using namespace std;int d[10][10],digit[10];//d[i][j] 表示有i位数字,且第一位是j的数字的 满足题意的数量void init(){d[0][0]=1;for(int i=1;i<=7;i++)for(int j=0;j<=9;j++)for(int k=0;k<=9;k++)if(j!=4&&!(j==6&&k==2))d[i][j]+=d[i-1][k];}int solve(int x) // [0,x){int len=0;while(x){digit[++len]=x%10;x/=10;}digit[len+1]=0;int ans=0;for(int i=len;i>=1;i--){for(int j=0;j<digit[i];j++)if(j!=4&&!(j==2&&digit[i+1]==6))ans+=d[i][j];if(digit[i]==4||(digit[i+1]==6&&digit[i]==2))break;}return ans;}int main(int argc, char const *argv[]){int n,m;init();while(cin>>n>>m,n+m)cout<<solve(m+1)-solve(n)<<endl;//由于要找[n,m],而solve函数找的范围为<n,所以传参的时候应该特别注意return 0;}




0 0