hdu5389(dp+数学)

来源:互联网 发布:nba2k16奥尼尔捏脸数据 编辑:程序博客网 时间:2024/05/21 11:17

链接:点击打开链接

题意:给出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/30972581int 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;}

0 0
原创粉丝点击