【HDU3652】B-number 数位DP
B-number
Problem Description
A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string "13" and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task is to calculate how many wqb-numbers from 1 to n for a given integer n.
Input
Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).
Output
Print each answer in a single line.
Sample Input
13
100
200
1000
Sample Output
1
1
2
2
题意:求n以内所有能被13整除且数字里包含13的数的个数
题解:数位DP,用f[i][j][k]表示有i位,最高位为j,对13取模等于k,且数字里包含13的数的个数,g[i][j][k]表示有i位,最高位为j,对13取模等于k,且数字里不包含13的数的个数。
然后一位一位判断就可以了。
代码:
#include <stdio.h> #include <string.h> int n,m; int v[20]; int f[12][10][13],g[12][10][13],t[12]; int main() { int i,j,k,l,ans,rem,x; t[1]=1; for(i=2;i<=10;i++) t[i]=t[i-1]*10; for(i=0;i<=9;i++) g[1][i][i]=1; for(i=2;i<=10;i++) { for(j=0;j<=9;j++) { for(k=0;k<=9;k++) { for(l=0;l<=12;l++) { if(j==1&&k==3) { f[i][j][l]+=(j*t[i]+(k+1)*t[i-1]-1-l)/13-(j*t[i]+k*t[i-1]-1-l)/13; } else { f[i][j][l]+=f[i-1][k][((l-j*t[i])%13+13)%13]; g[i][j][l]+=g[i-1][k][((l-j*t[i])%13+13)%13]; } } } } } while(scanf("%d",&n)!=EOF) { memset(v,0,sizeof(v)); rem=m=ans=0; //此时答案的后i位对13取模应该等于rem x=n; while(x) { v[++m]=x%10; x/=10; } for(i=m;i>=1;i--) { for(j=0;j<v[i];j++) ans+=f[i][j][rem]; if(v[i]>3&&v[i+1]==1) { ans+=g[i][3][rem]; } if(v[i]==3&&v[i+1]==1) { ans+=n/13-(n/t[i]*t[i]-1)/13; break; } rem=((rem-v[i]*t[i])%13+13)%13; } printf("%d\n",ans); } return 0; }
| 欢迎来原网站坐坐! >原文链接<