H Harmony Pairs(数位dp)

题目链接


题目大意:

给你一个数n,问从0-n范围内,有多少对数满足a

解题思路:

这题就是裸的数位dp,可惜以前没写过求解数对的题目,太菜了,看了别人的代码,觉得还是挺好理解的 ,就是设置一个四维数组dp[][][][],第一维记录数位(每个数位dp都是),第二维记录位数和(因为有正有负,所以要向右即比0大的数偏移),第三维记录第一个数是否达到边界,第四维记录第二个数是否达到边缘

代码:

#include
#define pb emplace_back

using namespace std;

const int maxn = 1e3;
const int mod = 1e9+7;
typedef long long ll;
typedef pair<int,int> Pii;

template <typename T>inline void read(T& t){
    char c=getchar();t=0;
    int f=1;
    while(!isdigit(c)){
       if(c=='-')f=-1;
        c=getchar();
    }
    while(isdigit(c))t=t*10+c-48,c=getchar();
    t=f*t;
}

template <typename T,typename... Args> inline void read(T& t,Args&... args){
    read(t);read(args...);
}

string str;
ll dp[105][1810][2][2];

ll dfs(int pos,int sum,bool limita,bool limitb){
    if(pos<0){
        return sum>905;
    }
    if(dp[pos][sum][limita][limitb]!=-1){
        return dp[pos][sum][limita][limitb];
    }
    int upa=limita?str[pos]-'0':9;
    ll tmp=0;
    for(int i=0;i<=upa;i++){
        int upb=limitb?i:9;
        for(int j=0;j<=upb;j++){
            tmp+=dfs(pos-1,sum+j-i,limita&&i==upa,limitb&&j==upb);
            tmp%=mod;
        }
    }
    return dp[pos][sum][limita][limitb]=tmp;
}

int main(){
    memset(dp,-1,sizeof(dp));
    cin>>str;
    int r=str.size()-1;
    reverse(str.begin(),str.end());
    cout<<dfs(r,905,true,true)<<endl;
    return 0;
}

你可能感兴趣的:(数位dp,多校)