题意:给定一个int类型能够保存的整数n,求1~n中能被13整除而且包含13的数字的个数。例如13、2613等。
思路:数位dp,模板见hdu3555。这里需要单开一维记录第k位之前的数字除以13的余数。即dfs的m参数。pre参数的意义:0表示之前没有出现过13而且前一位不是1;1表示之前没有出现过13但是前一位为1;2表示之前已经出现过13了。
#include <cstdio> #include <cstring> using namespace std; int n,dp[12][13][3]; int d[12],len; int dfs(int k,int m,int pre,int limit){ if(k<0) return m==0 && pre==2; if(0==limit && dp[k][m][pre]!=-1) return dp[k][m][pre]; int last = limit?d[k]:9; int res = 0; for(int i = 0;i<=last;i++){ int mnow = (m*10+i)%13; if(pre==0 || (pre==1 && i!=3)) res += dfs(k-1, mnow, i==1, limit&&(i==last)); else res += dfs(k-1, mnow, 2, limit&&(i==last)); } if(0==limit) dp[k][m][pre] = res; return res; } int solve(int x){ len = -1; while(x){ d[++len] = x%10; x /= 10; } return dfs(len,0,0,1); } int main(){ memset(dp,-1,sizeof(dp)); while(scanf("%d",&n)!=EOF) printf("%d\n",solve(n)); return 0; }