2015 多校联赛 ——HDU5389(dp)

Sample Input
4 3 9 1 1 2 6 3 9 1 2 3 3 5 2 3 1 1 1 1 1 9 9 9 1 2 3 4 5 6 7 8 9
 
Sample Output
1 0 10 60

题意:

已知有两个门,要求将人分为两组,两组的“和”分别等于两个门的数字,当然也可以全部进入一个门

思路:(NeverMoreH

如果能找到满足题意的解,一定满足a和b的和等于n个人的标号的和,所以我们只需要判断n个人的标号组成a的情况有多少(或者只判断b,一样),同时还要注意可以把n个人都分给a,或者都分给b,这样也是满足的。(果然还是缺乏经验- -,想不到方法)


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
#define N 500010
#define mod 258280327

int q[100050];
int dp[100005][10];

int Sum(int x,int y)
{
    int temp = x + y;
    int ans = temp % 9;
    if(ans == 0)
        return 9;
    return ans;
}

int main()
{
    int T,n,a,b;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&a,&b);
        int sum = 0;
        for(int i = 1; i <= n ; i++)
        {
            scanf("%d",&q[i]);
            sum = Sum(sum,q[i]);
        }
        memset(dp,0,sizeof(dp));
        dp[0][0] = 1;

        for(int i = 1; i <= n; i++)
            for(int j = 0; j <= 9; j++)
            {
                dp[i][j]+=dp[i-1][j];
                dp[i][Sum(j,q[i])] +=dp[i-1][j];
                dp[i][j] %= mod;
                dp[i][Sum(j,q[i])] %= mod;
            }
        int ans = 0;

        ans = (ans+dp[n][a]) * (Sum(a,b) == sum);

        if(sum == a && ans == 0)
            ans++;
        if(sum == b)
            ans++;
        printf("%d
",ans);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/Przz/p/5409780.html