习题:Horse Races(数位DP)
题目
思路
我们注意到每个数的状态实际上之和上一个幸运数字的位置相关
也就是指我们只需要枚举当前位置是不是幸运数字即可
计数的问题用数位DP解决就可以了
考虑\(dp_{i,j}\)第i位,上一个幸运数字的位置是在j
代码
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int mod=1e9+7;
int t,k;
int limit[1005],len;
long long dp[1005][1005][2];
char sl[1005],sr[1005];
long long dfs(int pos,int pre,int s,int lim)
{
if(pos==-1)
return s;
if(dp[pos][pre][s]!=-1&&lim==0)
return dp[pos][pre][s];
long long ret=0;
for(int i=0;i<=(lim?limit[pos]:9);i++)
{
if(i==4||i==7)
ret=(ret+dfs(pos-1,pos,(pre&&(pre-pos)<=k)|s,lim&&i==limit[pos]))%mod;
else
ret=(ret+dfs(pos-1,pre,s,lim&&i==limit[pos]))%mod;
}
if(lim==0)
dp[pos][pre][s]=ret;
return ret;
}
long long calc(char *s)
{
len=strlen(s);
len--;
for(int i=0;i<=len;i++)
limit[i]=s[len-i]-'0';
return dfs(len,0,0,1);
}
int check()
{
vector<int> v;
len=strlen(sl);
for(int i=0;i<=len;i++)
if(sl[i]=='4'||sl[i]=='7')
v.push_back(i);
for(int i=1;i<v.size();i++)
if(v[i]-v[i-1]<=k)
return 1;
return 0;
}
int main()
{
ios::sync_with_stdio(false);
memset(dp,-1,sizeof(dp));
cin>>t>>k;
for(int i=1;i<=t;i++)
{
cin>>sl>>sr;
cout<<((calc(sr)-calc(sl)+check())%mod+mod)%mod<<'\n';
}
return 0;
}

浙公网安备 33010602011771号