2705 - 对抗赛

程序设计对抗赛疫有N(0<N<=50的整数)个价值互不相同的奖品,每个奖品的价值分别为S1,S2,S3......Sn(均为不超过100的正整数)。现将它们分给甲乙两队,为了使得甲乙两队得到相同价值的奖品,必须将这N个奖品分成总价值相等的两组。

编程要求:对给定N及N个奖品的价值,求出将这N个奖品分成价值相等级的两组,共有多少种分法?

例如:N=5,S1,S2,S3......Sn分别为1,5,3,8,9。则可分为{1,3,9}与{5,8},仅有1种分法。

例如:N=7,S1,S2,S3.......Sn分别为1,2,3,4,5,6,7。

有4种分法:

{1,6,7}与{2,3,4,5};

{2,5,7}与{1,3,4,6};

{3,4,7}与{1,2,5,6};

{1,2,4,7}与{3,5,6};


题目输入

compepe.in

输入文件中包含N及S1,S2,S3......Sn。(每两个相邻的数据之间有一个空格隔开)。

题目输出

compepe.out

输出文件包含一个整数,表示多少种分法的答案,数据若无解,则输出0。

输入/输出样例

题目输入

7
1 2 3 4 5 6 7

题目输出

4

C语言解答

#include "stdio.h"
int n,s;
int a[50],f[50001];
int main()
{
	int i,j;
	scanf("%d",&n);
	s=0;
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
		s+=a[i];
	}
	if(s%2)
		printf("0\n");
	else
	{
		f[0]=1;
		s/=2;
		for(i=0;i<n;i++)
		{
			for(j=s;j>=a[i];j--)
				if(f[j-a[i]])
					f[j]+=f[j-a[i]];
		}
		printf("%d\n",f[s]/2);
	}
	return 0;
}

C++解答

#include<iostream>  
#include<cstdio>  
#include<cstring>  
using namespace std;  
int dp[51][3010], p[55];  
int main()  
{  
//  freopen("a.txt","r",stdin);  
    int n, i, j, k;  
    while(cin >> n)  
    {  
        memset(dp,0,sizeof(dp));  
        int sum(0);  
        for(i = 1; i <= n; ++ i)  
        {  
            cin >> p[i];  
            sum += p[i];  
        }  
        if(sum % 2) { cout << '0' << endl; continue; }  
        dp[0][0] = 1;  
        for(i = 1; i <= n; ++ i)  
        {  
            for(j = 0; j <= sum/2; ++ j)  
            {  
                dp[i][j] = dp[i-1][j];  
                if(j - p[i] >= 0)  
                     dp[i][j] = dp[i][j] + dp[i-1][j-p[i]];  
            }  
        }  
        cout << dp[n][sum/2]/2 << endl;  
    }  
    return 0;  
}  
时间限制 1 秒
内存限制 128 MB
讨论 统计
上一题 下一题