1 2 3 4

牛客多校6 Harmony Pairs 数位dp

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\n",part(l));
    
    return 0;
}

 

posted @ 2020-09-12 09:47  Lesning  阅读(219)  评论(0)    收藏  举报