题意很简单就是要你寻找数字含有13字串并且能够被13整除的数。
我自己的写法和大佬的做法都不一样,时间也比他们的慢很多 ,跑了(200+ms)。
大佬的博客:https://blog.csdn.net/libin56842/article/details/10026063
大佬的DP是三维,而我用了四维,但我认为我的好理解一些,虽然效率不高
dp[pos][pre][mod][flag],表示第pos位,前一位是pre,模为mod,是否出现过13这个字串。
代码:
///#include<bits/stdc++.h>
///#include<unordered_map>
///#include<unordered_set>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<bitset>
#include<set>
#include<stack>
#include<map>
#include<new>
#include<vector>
#define MT(a,b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai=acos(-1.0);
const double E=2.718281828459;
const int MOD=1e9+7;
const int INF=0x3f3f3f3f;
int n,num[15],dp[15][15][15][2];
int dfs(int pos,int pre,int mod,bool lead,bool limit,bool flag)
{
if(pos==0) ///递归结束,判断是否正确
return mod==0&&flag==1;
if(!limit&&!lead&&dp[pos][pre][mod][flag]!=-1) ///该状态已经被访问过
return dp[pos][pre][mod][flag];
int up=limit?num[pos]:9; ///确定这一位的上限
int ans=0;
for(int i=0;i<=up;i++)
ans+=dfs(pos-1,i,(mod*10+i)%13,lead&&i==0,limit&&i==num[pos],(i==3&&pre==1)||flag); ///继续递归
if(!limit&&!lead) ///记忆化
dp[pos][pre][mod][flag]=ans;
return ans;
}
int slove(int x)
{
int sign=0;
while(x)
{
num[++sign]=x%10;
x=x/10;
}
memset(dp,-1,sizeof(dp));
return dfs(sign,0,0,true,true,0);
}
int main()
{
while(scanf("%d",&n)!=EOF)
printf("%d\n",slove(n));
return 0;
}