HDU 5389.Zero Escape
1010.Zero Escape
一个数的数字根只和它mod~9mod 9之后的值有关,只要类似背包就能完成人员分配的计算。
具体证明:数字根=\sum_{i=0}^{w}a_i∑i=0wai,数字=\sum_{i=0}^{w}10^i*a_i∑i=0w10i∗ai
数字-数字根=\sum_{i=0}^{w}(10^i-1)*a_i∑i=0w(10i−1)∗ai,这个数字在modmod 99域下为00
时间复杂度O(n)O(n)
#include<bits/stdc++.h> #define N 100010 #define LL long long #define MOD 258280327 using namespace std; int a[N]; int dp[N][10]; int main() { int T,n,A,B,sum; scanf("%d",&T); while(T--) { sum=0; scanf("%d%d%d",&n,&A,&B); for (int i=1;i<=n;i++) { scanf("%d",&a[i]); sum=(sum+a[i])%9; if (sum==0) sum=9; } memset(dp,0,sizeof(dp)); dp[1][a[1]]=1; for (int i=2;i<=n;i++) for (int j=1;j<=9;j++) { if (j>a[i]) dp[i][j]=(dp[i-1][j]+dp[i-1][j-a[i]])%MOD; else { dp[i][j]=(dp[i-1][j]+dp[i-1][j+9-a[i]])%MOD; if (j==a[i]) dp[i][j]=(dp[i][j]+1)%MOD; } } LL ans=0; int tmp=(A+B)%9; if (tmp==0) tmp=9; if (tmp==sum) { ans=dp[n][A]; if (sum==A) ans--; } if (sum==A) ans=(ans+1)%MOD; if (sum==B) ans=(ans+1)%MOD; printf("%I64d\n",ans); } }