2020牛客多校第六场H-Harmony Pairs(数位dp)

H-Harmony Pairs(数位dp)
在这里插入图片描述

题意:S(A)表示数字A的每一位数的和,S(24)=2+4=6,S(209)=2+0+9=11
求0到N中有多少对AB,使得S(A)>S(B) ,
0<=A<=B<=N<=10100

数位dp裸题,挺暴力的 dp[pos][sta][l1][l2]。
其中pos表示枚举到的下标
sta表示到pos之前AB的差值之和,为了避免出现负数,可以将其离散到999
l1表示A取数的上界 l2表示B取数的上界
sta-i+j是因为S(A)>S(B),A<=B所以sta-i+j

Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#define ll long long
using namespace std;
const int INF=0x3f3f3f3f;
const double pi=acos(-1.0),eps=1e-8;
const int maxn=1e5+10;
const ll mod=1e9+7;
int dp[105][2005][2][2];
int a[105];
string b;
int dfs(int pos,int sta,bool limit1,bool limit2)
{
    if(pos==-1)//枚举到末尾
        return sta>999;
    if(dp[pos][sta][limit1][limit2]!=-1)
        return dp[pos][sta][limit1][limit2];
    int up=limit1?a[pos]:9;
    int ans=0;
    for(int i=0; i<=up; i++)//枚举B
    {
        int up2=limit2?i:9;
        for(int j=0; j<=up2; j++)//枚举A
        {
            ans+=dfs(pos-1,sta+j-i,limit1&&(i==a[pos]),limit2&&(j==up2));
            ans%=mod;
        }
    }
    dp[pos][sta][limit1][limit2]=ans;
    return ans;
}
int solve(string x)
{
    int pos=0;
    for(int i=b.size()-1; i>=0; i--)
    {
        a[pos++]=b[i]-'0';
    }
    return dfs(pos-1,999,true,true);
}
int main()
{
    memset(dp,-1,sizeof dp);

    cin>>b;

    printf("%d\n",solve(b));
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值