链接:点击打开链接
题意:给出n个数和两个值A,B,要求将n个数分成两部分,使得每部分数和的数根的值等于A和B,求种数
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int MOD=258280327;
int cal(int s){
return (s-1)%9+1;
} //需要用到数根的性质
int v[100005],dp[100005][10]; //数根详细证明可以看http://www.zhihu.com/question/30972581
int main(){
int t,i,j,k,n,A,B,sum,tmp;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&A,&B);
sum=0;
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++){
scanf("%d",&v[i]);
sum+=v[i];
}
dp[0][0]=1;
for(i=1;i<=n;i++){
for(j=0;j<10;j++)
dp[i][j]=dp[i-1][j];
for(j=0;j<10;j++)
if(dp[i-1][j]){ //知道树根的公式也就知道了转移方程
tmp=cal(j+cal(v[i]));
dp[i][tmp]=(dp[i][tmp]+dp[i-1][j])%MOD;
}
}
if(cal(sum)==B) //全放到B的情况
dp[n][A]=(dp[n][A]+1)%MOD;
printf("%d\n",dp[n][A]);
}
return 0;
}