https://ac.nowcoder.com/acm/contest/5671/H
这个题前导0是无所谓的
dp[pos][a][b][up][up2],pos 100(位置),a,b1000(a数字和b数字的和),up,up2(a是否达到N的上界,b是否达到a的上界) 3,会超时,需要优化
试想一下对于 123****,213*****,321*****来说,搜索到第三个位置答案就已经知道了,不必继续搜索了,所以可以优化为 dp[pos][tes][up][up2],tes是B-A的值。
具体看代码吧
#include<bits/stdc++.h> using namespace std; typedef long long ll; int T,n,m,len,a[200]; ll l,r,dp[200][2000][3][3]; ll mod = 1e9+7; string sn; ll dfs(int pos,int tes,int up,int up2)//tes是a-b, { if(pos>len) return tes > 1000; if(dp[pos][tes][up][up2]!=-1 ) return dp[pos][tes][up][up2]; ll ret=0; int res=up?(sn[pos-1] - '0'):9;//最高位最大值 for(int i=0;i<=res;i++){ int b = 9; if(up2) b = i; for(int j=0;j<=b;j++){ ret = (ret + dfs(pos+1,tes + j - i,up && (i == res),up2 && (j == b)))%mod; } } //没有前导0和最高限制时可以直接记录当前dp值以便下次搜到同样的情况可以直接使用。 return dp[pos][tes][up][up2]=ret; } ll part(ll x) { len=sn.length(); memset(dp,-1,sizeof dp); return dfs(1,1000,1,1); } int main() { cin>>sn; printf("%lld ",part(l)); return 0; }