首页 > 代码库 > Baltic2008联合内阁

Baltic2008联合内阁

Description

     N个政党要组成一个联合内阁,每个党都有自己的席位数. 现在希望你找出一种方案,你选中的党的席位数要大于总数的一半,并且联合内阁的席位数越多越好. 对于一个联合内阁,如果某个政党退出后,其它党的席位仍大于总数的一半,则这个政党被称为是多余的,这是不允许的.

Input

     第一行给出有多少个政党.其值小于等于300 下面给出每个政党的席位数.总席位数小于等于 100000

Output

     你的组阁方案中最多能占多少个席位.

Algorithm

     这道题的意思讲得不明朗啊。大概意思是从若干个数中挑选出几个数,使这些被选出的数之和大于总和的一半,并且满足:被选出的数之和减去这些数中的最小数,得到的值小于总和的一半。然后用f[j]表示当前能不能使得数之和达到j,枚举i个数,若f[j]==true且j<=总数一半,就把j+a[i]标成true。

     这里还有一个细节,被选出的数之和减去这些数中的最小数,得到的值小于总和的一半。我们可以先将政党的人数先由大到小排序,我们由大到小枚举,这样就可以保证当前取的一定是所有已取得政党中的最小值。

Code

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int a[100100],n,ans,sum;
 6 bool f[100100];
 7 int main()
 8 {
 9   cin>>n;
10   ans=0;
11   for (int i=1;i<=n;i++) 
12   { 
13     cin>>a[i];
14     sum+=a[i];
15   } 
16   sort(a+1,a+n+1);
17   f[0]=true;
18   for (int i=n;i>=1;i--)
19     for (int j=sum/2;j>=0;j--)
20       if (f[j])
21       {
22         f[j+a[i]]=true;
23         if (j+a[i]>ans) ans=j+a[i];
24       }
25   cout<<ans<<endl;
26   return 0;
27 }

Source

     http://www.lydsy.com/JudgeOnline/problem.php?id=1334

Baltic2008联合内阁