HDU3652 B-number
题意:1到n含有13且整除13的数字个数
(f[d][q][one][has])表示d位余数为q上一位是否为1当前是否有13到0位时合法数字个数
除了天际线全都记忆化
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=15;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
int n, a[N], len, f[N][N][2][2];
int dfs(int d, int q, bool one, bool has, int sky) {
if(d==0) return q==0 && has;
if(!sky && f[d][q][one][has]!=-1) return f[d][q][one][has];
int lim= sky ? a[d] : 9, now=0;
for(int i=0; i<=lim; i++)
now += dfs(d-1, (q*10 + i)%13, i==1, has || (one && i==3), sky && i==lim);
return sky ? now : f[d][q][one][has]=now;
}
int cal(int n) {
memset(f,-1,sizeof(f));
len=0;
while(n) a[++len]=n%10, n/=10;
return dfs(len, 0, 0, 0, 1);
}
int main() {
freopen("in","r",stdin);
while(scanf("%d",&n)!=EOF) printf("%d
", cal(n));
}