dp--P2663越越的组队

题目描述

班级要组织一场综合能力竞赛,全班同学(N(100以内)个,N是偶数)分成两队互相竞争。老师找到了越越并给了越越一张全班同学综合能力测试的成绩,要求他从全班同学中选出一半(他自己也可能被选),并要求这些同学综合能力测试的成绩之和在不超过班级总分一半的前提下尽量达到最高。这样分成的两队实力是最平均的。越越堆着满脸的笑容找到了你,你就帮他写一个程序吧。

输入格式

第一行:学生个数N;第二行开始的N行每行一个同学的综合能力测试的成绩。

输出格式

输出一个数:N/2个同学的综合能力测试的成绩之和在不超过班级总分一半的前提下尽量达到的最高值。

首先求出所有综合能力的总分和/2,因为要求所选同学的综合能力测试的成绩只和在不超过班级总分的一半

所以每次for循环从ave(班级总分的一半)开始,每次--1,即能保证每次选一个同学后都不超出ave

因为要求所选同学综合成绩的和最大,两队最平均,所以 dp[j]=max(dp[j],dp[j-a[i]]+a[i])取大的一个。

1  for(int i=1;i<=n;i++) {
2         for(int j=ave;j>=a[i];j--) {
3             dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
4             tmp=max(tmp,dp[j]);
5         }
6     }

其中dp[j]表示总分上线为j时,所选同学总和的上限值

每一次都是在所剩总分大于等于当前同学总分时,才选择一个大的值

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 int n,a[110];
 6 int dp[11000];
 7 int main()
 8 {
 9     scanf ("%d",&n);
10     int ans=0;
11     for (int i = 1;i <= n;i++)
12     {
13         scanf ("%d",&a[i]);
14         ans+=a[i];
15     }
16     int ave=ans/2;
17     int tmp=0;
18      for(int i=1;i<=n;i++) {
19         for(int j=ave;j>=a[i];j--) {
20             dp[j]=0;
21           
22         }
23     }
24    for(int i=1;i<=n;i++) {
25         for(int j=ave;j>=a[i];j--) {
26             dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
27             tmp=max(tmp,dp[j]);
28         }
29     }
30     cout<<tmp<<endl;
31     return 0;
32 }

猜你喜欢

转载自www.cnblogs.com/very-beginning/p/11952833.html