SRM 591 DIV2 1000

Problem Statement

    Manao is the coach of a soccer team. There are N boys numbered from 0 to N-1 on the team. Each of them has some level of soccer skill. Manao would like to divide the boys into two teams for today's training. The division should satisfy the following conditions:
  • Each boy is assigned to a team.
  • The total skill of first team is strictly greater than the total skill of the second team.
  • For each player P in the first team: if we were to move P into the second team, the total skill of the first team would become strictly smaller than the total skill of the second team.
The total skill of a team is the sum of skills of the boys on that team.

You are given a vector <int> skill containing N elements. The i-th element in skill is the skill of boy i. Manao is interested in the number of ways to perform such a division into teams. Please compute and return this number.

Definition

    
Class:YetAnotherTwoTeamsProblem
Method:count
Parameters:vector <int>
Returns:long long
Method signature:long long count(vector <int> skill)
(be sure your method is public)

Limits

    
Time limit (s):2.000
Memory limit (MB):64

Constraints

-skill will contain between 2 and 50 elements, inclusive.
-Each element of skill will be between 1 and 60,000, inclusive.

Examples

0) 
    
{5, 4, 7, 6}
Returns: 2
The two possible divisions are:
  • Boys 0 and 2 against boys 1 and 3.
  • Boys 2 and 3 against boys 0 and 1.
1) 
    
{1, 1, 1, 1, 1}
Returns: 10
Manao can put any three boys on the first team.
2) 
    
{1, 2, 3, 5, 10}
Returns: 5
The possible choices of the first team are:
  • Boys 0 and 4.
  • Boys 1 and 4.
  • Boys 2 and 4.
  • Boys 3 and 4.
  • Boys 0, 1, 2 and 3.
3) 
    
{1, 2, 3, 4, 10}
Returns: 0
 
4) 
    
{999, 999, 999, 1000, 1000, 1001, 999, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000,
 1000, 1000, 1000, 999, 1000, 512, 511, 1001, 1001, 1001, 1001, 1001, 1000}
Returns: 17672631900
 

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.

题目描述:给你一组数,要求你将这组数分为两组,使得第一组的数之和严格大于第二组数之和,并且第一组数任意一个数移到第二组数时,第一组数之和严格小于第二组数之和。

解题思路:先用sum求所有数的总和,用dp[x]表示第二组数之和为x的方案数。将skill[ ]sort一遍。再从后往前枚举skill[i],同时枚举第一组数的总和j。如果{j-skill[i]<sum-(j-skill[i])}并且{j>sum-j}那么ans+=dp[j-skill[i]];初始化为dp[0]=1;

代码:

long long YetAnotherTwoTeamsProblem::count(vector <int> skill) {
	ans=sum=t=0;
	memset(dp,0,sizeof(dp));
	for(long long i=0;i<skill.size();i++)
		sum+=skill[i];	
	sort(skill.begin(),skill.end());
	dp[0]=1;
	for(long long i=skill.size()-1;i>=0;i--)
	{
		t+=skill[i];
		for(long long j=min(t,sum/2+skill[i]);j>=skill[i];j--)
		{
			if(dp[j-skill[i]])
			{
				dp[j]+=dp[j-skill[i]];
				long long tmp=dp[j-skill[i]];
				if((j-skill[i])<(sum-j+skill[i])&&j-(sum-j)>0)ans+=tmp;
			}
		}
	}
	return ans;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值