B-number HDU

//dp[i][j][0]表示i位数模13为j当前没有包含13并且最高位不为1的方案数;
//dp[i][j][1]表示i位数模13为j当前没有包含13并且最高位为1的方案数;
//dp[i][j][2]表示i位数模13为j当前包含13的方案数。
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 15
using namespace std;
int bit[N],dp[N][N][3];
//遍历到的位置,前面的位数%13的余数
//have: 是否有13
// 
int dfs(int pos,int mod,int have,int lim) 
{
	int num,ans,mod_x,have_x;
	if(pos<=0) 
		return mod==0&&have==2;
	if(!lim&&dp[pos][mod][have]!=-1)
		return dp[pos][mod][have];
	num=lim?bit[pos]:9;
	ans=0;
	for(int i=0; i<=num; i++) {
		//秦九韶算法 
		mod_x=(mod*10+i)%13;
		have_x=have;
		//如果前面前一位不是1
		//这一位是1
		//标记有1 
		if(have==0&&i==1) 
			have_x=1;
		//如果前一位是1
		//当前位不是1
		//那么就标记没有 
		if(have==1&&i!=1) 
			have_x=0;
		//如果前一位是1
		//当前位是3
		//也就是有13,标记有 
		if(have==1&&i==3) 
			have_x=2;
		//往下递归 
		ans+=dfs(pos-1,mod_x,have_x,lim&&i==num);
	}
	//只有不受限的时候,才记录答案 
	if(!lim) 
		dp[pos][mod][have]=ans;
	return ans;
}
int main() {
	int n,len;
	while(scanf("%d",&n)!=EOF) {
		memset(bit,0,sizeof(bit));
		memset(dp,-1,sizeof(dp));
		len=0;
		while(n)
		{
			bit[++len]=n%10;
			n/=10;
		}
		printf("%d
",dfs(len,0,0,1));
	}
	return 0;
}
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12500175.html