还是记忆化搜索的方法,dp数组加了一位用于保存mod。只不过这一维只用于保存,没有任何用处。我们想的时候不要用三维空间想,越想过程越麻烦。
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
typedef long long LL;
const int N = 21;
const int INF = 1e8;
int dp[N][14][5], bit[N];
int dfs(int pos, int pre, int mod, bool limit, bool flag)
{
if(pos == 0) return flag && (mod == 0);
if(!limit && flag && dp[pos][mod][0] != -1) return dp[pos][mod][0];
if(!limit && !flag && pre != 1 && dp[pos][mod][2] != -1) return dp[pos][mod][2];
if(!limit && !flag && pre == 1 && dp[pos][mod][1] != -1) return dp[pos][mod][1];
int endd = limit ? bit[pos] : 9;
int ans = 0;
for(int i = 0; i <= endd; i ++)
{
ans += dfs(pos - 1, i, (mod * 10 + i) % 13, limit && (i == endd), flag || (pre == 1 && i == 3));
}
if(!limit)
{
if(flag) dp[pos][mod][0] = ans;
if(!flag && pre != 1) dp[pos][mod][2] = ans;
if(!flag && pre == 1) dp[pos][mod][1] = ans;
}
return ans;
}
int solve(int n)
{
int len = 0;
while(n)
{
bit[++ len] = n % 10;
n /= 10;
}
return dfs(len, 0, 0, true, false);
}
int main()
{
// freopen("in.txt", "r", stdin);
int num;
while(~scanf("%d", &num))
{
memset(dp, -1, sizeof(dp));
printf("%d\n", solve(num));
}
return 0;
}