You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
int s1, s2, s3, s4; //4科的题目数量
|
|
|
|
|
|
|
|
|
|
//20是每个科目的题目数量上限
|
|
|
|
|
//60是每道题消耗的最长时间上限
|
|
|
|
|
//题目数据上限为20*60,这里设置为1210,保证不会越界
|
|
|
|
|
const int N = 610; //背包的最大容量是 20*60,我们设置1200就可以,但实际上我们只需要一半的容量,就是610就行了。
|
|
|
|
|
int w[N], v[N], f[N];
|
|
|
|
|
|
|
|
|
|
int bag(int n) {
|
|
|
|
|
int sum = 0; //当前科目中所有习题的时长总和
|
|
|
|
|
memset(f, 0, sizeof(f));
|
|
|
|
|
|
|
|
|
|
for (int i = 1; i <= n; i++) {
|
|
|
|
|
cin >> w[i];
|
|
|
|
|
v[i] = w[i]; //此题中的价值v和重量w是同一个概念,背包上限的是总时间的一半,放入一个习题,就占用了v[i]的时间,产生了v[i]的价值
|
|
|
|
|
sum += w[i]; //总时长
|
|
|
|
|
}
|
|
|
|
|
//总时长的一半,就是尽量想办法装满一半的容量
|
|
|
|
|
int m = sum / 2;
|
|
|
|
|
|
|
|
|
|
//01背包模板
|
|
|
|
|
for (int i = 1; i <= n; i++)
|
|
|
|
|
for (int j = m; j >= w[i]; j--) // sum/2就是背包的上限,因为一半尽量装满,则不是这半最佳就是另一半最佳。
|
|
|
|
|
f[j] = max(f[j], f[j - w[i]] + v[i]);
|
|
|
|
|
|
|
|
|
|
//两半取最大的一半就是本科目的时长
|
|
|
|
|
return max(f[m], sum - f[m]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
//需要考4科
|
|
|
|
|
cin >> s1 >> s2 >> s3 >> s4;
|
|
|
|
|
int ans = bag(s1) + bag(s2) + bag(s3) + bag(s4); //一科一科的整,四个背包最优解的总和
|
|
|
|
|
cout << ans << endl;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|