数位dp基础题目

来源:互联网 发布:淄博网站排名seo 编辑:程序博客网 时间:2024/06/03 05:07
/********************language:c++  author:piratesproblem:hdu2089 style:数位dp *********************/#include<iostream>#include<stdio.h>#include<algorithm>using namespace std;#define Maxx 1000010int dp[10][10];//dp[i][0] 代表不是不吉利的个数//dp[i][1] 代表最高位为2的个数且是非不吉利数 //dp[i][2] 代表不吉利个数的总数,62或4都不能存在 void Init(){dp[0][0]=1;for(int i=1;i<=6;i++){dp[i][0]=dp[i-1][0]*9-dp[i-1][1];//最高位除了4,选择其它9个数,但在2之前可能存在6,所以要减去第二位2的个数dp[i][1]=dp[i-1][0]; //最高位只有2可以选 dp[i][2]=dp[i-1][2]*10+dp[i-1][0]+dp[i-1][1];//}}int Solve(int n){int i,j,flag=0;int bit[10];int len=0;int tem=n;while(n){bit[++len]=n%10;n/=10;}bit[len+1]=0;int ans=0;for(int i=len;i>=0;i--){ans+=dp[i-1][2]*bit[i]; //存在不吉利的数的总数 if(flag)ans+=dp[i-1][0]*bit[i];else {if(bit[i]>4)ans+=dp[i-1][0]; //高位可能出现4的情况  if(bit[i+1]==6&&bit[i]>2) ans+=dp[i][1];//高位为6,第二为可能为2的情况  if(bit[i]>6) ans+=dp[i-1][1]; if(bit[i]==4 || (bit[i+1]==6&&bit[i]==2))flag=1;}}return tem-ans;} int main(){int n,m,i,j;Init();while(scanf("%d%d",&n,&m)){if(!n&&!m) break;printf("%d\n",Solve(m+1)-Solve(n));}return 0;}
/********************language:c++  author:piratesproblem:hdu3555style:数位dp *********************/#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;//dp[i][0] 代表不出现49的个数//dp[i][1] 最高位为9的个数//dp[i][2] 出现49的 个数 typedef __int64 ll;ll dp[30][3];void Init(){ll i;memset(dp,0,sizeof(dp)); dp[0][0]=1; for(i=1;i<=30;i++){dp[i][0]=(ll)dp[i-1][0]*10-dp[i-1][1]; //不出现49的个数 dp[i][1]=(ll)dp[i-1][0];//最高位为9的个数dp[i][2]=(ll)dp[i-1][2]*10+dp[i-1][1]; //出现49的个数 } } ll Solve(ll n){ll i,j,len=0;ll bit[25]; while(n){bit[++len]=n%10;n/=10;}bit[len+1]=0;ll ans=0;ll flag=0;for(i=len;i>0;i--){ans+=(ll)dp[i-1][2]*bit[i];if(flag)ans+=(ll)dp[i-1][0]*bit[i]; else{if(bit[i]>4)ans+=dp[i-1][1];if(bit[i+1]==4 && bit[i]==9)flag=1;}}return ans;}int main(){Init();ll n,m,T;scanf("%I64d",&T);while(T--){scanf("%I64d",&n);printf("%I64d\n",Solve(n+1));}return 0;}
/***************language:c++  author:piratesproblem:相邻两数差2 style:数位dp****************/ #include<iostream>#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;int dp[15][10];void Init(){int i,j,k;memset(dp,0,sizeof(dp));for(i=0;i<10;i++)dp[1][i]=1;for(i=2;i<=10;i++)for(j=0;j<10;j++)for(k=0;k<10;k++)if(abs(j-k)>=2)dp[i][j]+=dp[i-1][k];  }int Solve(int n){int len=0,i,j,bit[15];while(n){bit[++len]=n%10;n/=10;}bit[len+1]=0;int ans=0;for(i=1;i<len;i++)//统计每位的情况 for(j=1;j<bit[i];j++)ans+=dp[i][j];for(i=1;i<bit[len];i++)//最高位的情况 ans+=dp[len][i];for(i=len-1;i;i--)//for(j=0;j<bit[i];j++){if(abs(j-bit[i+1])>=2)ans+=dp[i][j];if(abs(bit[i+1]-bit[i])<2) break;}return ans;}int main(){Init();int i,j,n,m;scanf("%d%d",&n,&m);printf("%d\n",Solve(m+1)-Solve(n));return 0;}