来源:http://acm.hdu.edu.cn/showproblem.php?pid=3652
题意:求1到n中有多少个数含有'13'串。
分析:很明显的数位dp,网上现在都有现成的模板了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
#include <queue>
#include <cmath>
#include <stack>
#include <set>
#include <vector>
#include <climits>
using namespace std;
int dp[20][14][3];
int bit[20],ten[20];
int dfs(int pos,int mod,int have,int limit)//limit 有上限为1 无上限为0
{
if(pos==-1)
return have==2&&mod==0;
if(!limit&&dp[pos][mod][have]!=-1)
return dp[pos][mod][have];//当前状态访问过,没有上限
int end=limit?bit[pos]:9;
int ans=0;
for(int i=0;i<=end;i++)
{
int nmod=(mod*10+i)%13;
int nhave=have;
if(have==0&&i==1)//高位不含13,并且末尾不是1 ,现在末尾添1
nhave=1;
if(have==1&&i!=1)//高位不含13,且末位是1,现在末尾添加的不是1返回0状态
nhave=0;
if(have==1&&i==3)//高位不含13,且末尾是1,现在末尾添加3返回2状态
nhave=2;
ans+=dfs(pos-1,nmod,nhave,limit&&i==end);
}
if(!limit)
dp[pos][mod][have]=ans;
return ans;
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
ten[0]=1;
for(int i=1; i<20; i++)
ten[i]=ten[i-1]*10;
int n;
while(cin>>n)
{
memset(bit,0,sizeof(bit));
memset(dp,-1,sizeof(dp));
int x=0;
while(n)
{
bit[x++]=n%10;
n/=10;
}
cout<<dfs(x-1,0,0,1)<<endl;
}
return 0;
}