http://acm.hdu.edu.cn/showproblem.php?pid=3652
题意:如果一个数含有‘13’并且可以被13整除,就叫他b数,对于给定N求不大于N 的b数的个数。
题解:数位DP模板题。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll dp[22][14][3];
int a[22];
ll dfs(int pos,int sta,int mod,bool limit){
if(pos==-1)return mod==0&&sta==2;
if(!limit&&dp[pos][mod][sta]!=-1)return dp[pos][mod][sta];
int i,up,nsta;
ll tmp=0;
up= limit?a[pos]:9;
for(i=0;i<=up;i++){
nsta=sta;
if(sta==1&&i==3)nsta=2;//有13
else if(sta==1&&i!=1)nsta=0;//原来有1但是这波没了
else if(sta==0&&i==1)nsta=1;//原来没1这波有了
tmp=tmp+dfs(pos-1,nsta,(mod*10+i)%13,limit&&a[pos]==i);//原本是2,与上次是1这次还是1和原本是不是1这次还不是1被直接继承
}
if(!limit)dp[pos][mod][sta]=tmp;
return tmp;
}
ll solve(ll x){
int pos=0;
while(x>0){
a[pos++]=x%10;
x/=10;
}
return dfs(pos-1,0,0,true);
}
int main()
{
ll l;
while(~scanf("%lld",&l)){
memset(dp,-1,sizeof(dp));
printf("%lld\n",solve(l));
}
//cout << "Hello world!" << endl;
return 0;
}