牛客网Harmony Pairs

链接:https://ac.nowcoder.com/acm/contest/5671/H
来源:牛客网

题目描述

Roundgod is obsessive about numbers.
Let S(x)S(x)S(x) be the sum of the digits of xxx in decimal notation, (A,B)(A,B)(A,B) is a harmony pair if and only if S(A)>S(B)S(A)>S(B)S(A)>S(B).
Roundgod is given NNN, and she wants to count the number of harmony pairs (A,B)(A,B)(A,B) modulo 109+710^9+7109+7 satisfying 0≤A≤B≤N0\le A\le B\le N0ABN.
 
翻译:

设S(x)表示十进制表示下x的每位数字之和,当 时,(A,B)表示一个和谐对。

给定N,求满足 的和谐对 的数量,答案对 取模。

 

 

 

很显然这是一道数位DP。

状态dp[x][d][l][s]中

  • x:表示位置。
  • d:A前面位数和−B前面位数和.(注:要防负数)
  • I:limit,当前位之前B是否等于N,并反映限制 B ≤ N
  • s:当前位之前A是否等于B,反映限制A≤B

这样一来,那么题目就迎刃而解了。

代码如下:

#include<bits/stdc++.h>
const int N=110,mod=1e9+7;
using namespace std;
int n,digit[N],dp[N][N*20][2][2];
char s[N];
int dfs(int x,int d,bool l,bool s)
{
    if(!x) return d>1000;
    if(~dp[x][d][l][s])
        return dp[x][d][l][s];
    int ret=0,lim=l?digit[x]:9;
    for(int i=0;i<=lim;i++)
        for(int j=0;j<=(s?i:9);j++)
            ret=(ret+dfs(x-1,d+j-i,l&(digit[x]==i),s&(i==j)))%mod;
    return dp[x][d][l][s]=ret;     
}
int main()
{
    memset(dp,-1,sizeof(dp));
    scanf("%s",s);
    n=strlen(s);
    for(int i=0;i<n;i++)
        digit[n-i]=s[i]-'0';
    printf("%d\n",dfs(n,1000,1,1));
}
View Code

 

posted @ 2020-07-28 14:00  mdID(WWWZZZQQQ)  阅读(323)  评论(0)    收藏  举报