1 条题解
-
0
自动搬运
来自洛谷,原作者为

kkksc03
洛谷吉祥物 DA✩ZE搬运于
2025-08-24 21:24:52,当前版本为作者最后更新于2013-08-12 22:35:37,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
By tinylic
如果没有b[i]这个属性的话就是明显的01背包问题。
现在考虑相邻的两个物品x,y。假设现在已经耗费p的时间,那么分别列出先做x,y的代价:
a[x]-(p+c[x])*b[x]+a[y]-(p+c[x]+c[y])*b[y] (①)
a[y]-(p+c[y])*b[y]+a[x]-(p+c[y]+c[x])*b[x] (②)
对这两个式子化简,得到①>②的条件是c[x]*b[y]<c[y]*b[x].
发现只要满足这个条件的物品对(x,y),x在y前的代价永远更优。
因此可以根据这个条件进行排序,之后就是简单的01背包了。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define LL long long #define maxn 100001 using namespace std; struct node { int a, b, c; }a[maxn]; LL f[maxn], ans; int T, n, i, j; bool cmp(node a, node b) { return (LL)a.c * (LL)b.b < (LL)b.c * (LL)a.b; } int main() { scanf("%d%d", &T, &n); for (i = 0; i < n; i++) scanf("%d", &a[i].a); for (i = 0; i < n; i++) scanf("%d", &a[i].b); for (i = 0; i < n; i++) scanf("%d", &a[i].c); sort(a, a + n, cmp); memset(f, 255, sizeof f); f[0] = 0; for (i = 0; i < n; i++) { for (j = T; j >= 0; --j) if (f[j] != -1 && j + a[i].c <= T) f[j + a[i].c] = max(f[j + a[i].c], f[j] + (LL)a[i].a - (LL)(j + a[i].c) * (LL)a[i].b); } for (i = 0; i <= T; i++) ans = max(ans, f[i]); cout << ans << endl; }
- 1
信息
- ID
- 411
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者