题意:给定长度不超过2000的a,b;问有多少个x(a<=x<=b)使得x的偶数位为d,奇数位不为d;结果mod 1e9+7;
直接数位DP;注意在判断是否f[pos][mod] != -1之前,要判断是否为边界,否则会出现重复计算;
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define MS1(a) memset(a,-1,sizeof(a)) const int N = 2005,MOD = 1e9+7; char a[N],b[N]; int f[N][N][2],n,m,d; int dfs(char* s,int p,int mod,int on = 1) { if(p == n) return mod == 0; int& ans = f[p][mod][on]; if(ans != -1) return ans; ans = 0; for(int i = 0;i <= (on?s[p] - ‘0‘:9);i++){ if(p%2 && i != d) continue; if(p%2 == 0 && i == d) continue; (ans += dfs(s,p+1,(mod*10+i)%m,on && i == s[p] - ‘0‘)) %= MOD; } return ans; } int calc(char* s) { MS1(f); return dfs(s,0,0); } int main() { scanf("%d%d",&m,&d); scanf("%s%s",a,b); n = strlen(a); for(int i = n-1;i >= 0;i--){ if(a[i] == ‘0‘) a[i] = ‘9‘; else{a[i]--;break;} } printf("%d",(calc(b)-calc(a)+MOD)%MOD); }
还有一种就是增加一维[2],用来存储是否为边界;大同小异
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define MS1(a) memset(a,-1,sizeof(a)) const int N = 2005,MOD = 1e9+7; char a[N],b[N]; int f[N][N][2],n,m,d; int dfs(char* s,int p,int mod,int on = 1) { if(p == n) return mod == 0; int& ans = f[p][mod][on]; if(ans != -1) return ans; ans = 0; for(int i = 0;i <= (on?s[p] - ‘0‘:9);i++){ if(p%2 && i != d) continue; if(p%2 == 0 && i == d) continue; (ans += dfs(s,p+1,(mod*10+i)%m,on && i == s[p] - ‘0‘)) %= MOD; } return ans; } int calc(char* s) { MS1(f); return dfs(s,0,0); } int main() { scanf("%d%d",&m,&d); scanf("%s%s",a,b); n = strlen(a); for(int i = n-1;i >= 0;i--){ if(a[i] == ‘0‘) a[i] = ‘9‘; else{a[i]--;break;} } printf("%d",(calc(b)-calc(a)+MOD)%MOD); }
时间: 2024-10-11 22:30:51