@guxier
2022-03-24T07:54:25.000000Z
字数 2626
阅读 818
洛谷 搜索
kkksc03 的大学生活非常的颓废,平时根本不学习。但是,临近期末考试,他必须要开始抱佛脚,以求不挂科。
这次期末考试,kkksc03 需要考4科。因此要开始刷习题集,每科都有一个习题集,分别有 道题目,完成每道题目需要一些时间,可能不等
kkksc03 有一个能力,他的左右两个大脑可以同时计算2道不同的题目,但是仅限于同一科。因此,kkksc03 必须一科一科的复习。
由于 kkksc03 还急着去处理洛谷的 bug,因此他希望尽快把事情做完,所以他希望知道能够完成复习的最短时间。
本题包含 5 行数据:第1行,为四个正整数
第 2 行,为 共个数,表示第一科习题集每道题目所消耗的时间。
第 3 行,为 共 个数。
第 4 行,为 共 个数。
第 5 行,为 共 个数,意思均同上。
输出一行,为复习完毕最短时间。
输入输出样例
1 2 1 354 362 4 3
20
数据量是20所以直接暴力枚举,也不会超时
用时 81ms 结果
#include <cstdio>#include <vector>#include <queue>#include <cstring>#include <map>#include <set>#include <cmath>#include <iostream>#include <algorithm>#define ios ios::sync_with_stdio(false), cin.tie(0)#define sd(n) scanf("%d", &n)#define rep(i, a, n) for (int i = a; i <= n; i++)#define per(i, a, n) for (int i = n; i >= a; i--)#define fs first#define se second#define debug(x) cout << #x << ": " << x << endl#define MOD 1000000007#define INF 0x3f3f3f3ftypedef long long ll;using namespace std;const int N = 1e4 + 10;int s[5], a[21], sum, ans, l ,r;void search(int i,int x){if(i > x){sum = min(sum, max(l,r));return;}//回溯l += a[i];search(i+1,x);l -= a[i];r += a[i];search(i+1,x);r -= a[i];}int main(){rep(i, 1, 4) cin >> s[i];rep(i, 1, 4){l = r = 0;sum = INF;rep(j, 1, s[i])cin >> a[j];search(1, s[i]);ans += sum;}cout << ans;return 0;}
时间是体积,也是价值,对于每一门课有n个物品,体积为sum/2(sum为时间总和)的01背包即可。
用时 30ms 结果
#include <cstdio>#include <vector>#include <queue>#include <cstring>#include <map>#include <set>#include <cmath>#include <iostream>#include <algorithm>#define ios ios::sync_with_stdio(false), cin.tie(0)#define sd(n) scanf("%d", &n)#define rep(i, a, n) for (int i = a; i <= n; i++)#define per(i, a, n) for (int i = n; i >= a; i--)#define fs first#define se second#define debug(x) cout << #x << ": " << x << endl#define MOD 1000000007#define INF 0x3f3f3f3ftypedef long long ll;using namespace std;const int N = 1e4 + 10;int s[5], sum, a[21], ans;int dp[N];int main(){rep(i, 1, 4) cin >> s[i];rep(i, 1, 4){sum = 0; //时间总和memset(dp, 0, sizeof dp);rep(j, 1, s[i]){cin >> a[j];sum += a[j];}rep(k, 1, s[i])for(int j = sum/2; j >= a[k]; j--)dp[j] = max(dp[j], dp[j-a[k]] + a[k]);ans += max(dp[sum/2], sum - dp[sum/2]);}cout << ans;return 0;}