1. 程式人生 > 實用技巧 >牛客網Harmony Pairs

牛客網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) modulo109+710^9+7109+7satisfying 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