HDU3652,B-number(数位DP)

用数位DP。
状态:dp[i,j,k,state]表示枚举到第i位时,前一位数字为j,前面各个数字组成的数mod13=k,当前是否包含“13”串(state=0否state=1是),符合条件的数字的总个数
边界:return (state && !k)? 1:0
代码如下:

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
ll dp[11][11][15][2];
int digit[11];

ll dfs(int pos,int pre,ll ori,int state,bool limit)
{
	if(pos==-1)	
	{
		if(state&&!ori)	return 1;
		return 0;
	}
	if(!limit&&dp[pos][pre][ori][state]!=-1)	return dp[pos][pre][ori][state];
	ll ret=0;
	int up= limit? digit[pos]:9;
	for(int i=0;i<=up;++i)
		ret+=dfs(pos-1,i,(ori*10+i)%13,state||(pre==1&&i==3),limit&&i==digit[pos]);
	if(!limit)	dp[pos][pre][ori][state]=ret;
	return ret;
}

ll solve(ll n)
{
	int pos=0;
	while(n)
	{
		digit[pos++]=n%10;
		n/=10;
	}
	return dfs(--pos,10,0,0,1);
}
int main()
{
	ll n;
	memset(dp,-1,sizeof(dp));
	while(~scanf("%lld",&n))
	{
		printf("%lld\n",solve(n));
	}
	return 0;
}

你可能感兴趣的:(数位DP,数位DP)