Luogu 1417 烹调方案 解题报告
一共有
n 件食材,每件食材有三个属性,a_i ,b_i 和c_i ,如果在t 时刻完成第i 样食材则得到a_i-t*b_i 的美味指数,用第i 件食材做饭要花去c_i 的时间。在
T 时间内设计烹调方案使得美味指数最大
解题思路:
显然是一个01背包,但是,当你写完01背包板子交上去以后会发现只有30分。
题目中给了一个条件:在
设
将两个物品可获得的值表示出来为:
设
拆项得
化简得
由此,我们就得到了我们 sort 函数中cmp的写法。注意开 long long 这题就完了。
这题的关键就在此,我不知道是为什么,大部分题解中都没有给出自己的完整证明,这个证明也不难证,希望读者看完后可以自己证明一遍。
代码:
#include <cstdio>
#include <cctype>
#include <algorithm>
#define int long long
using namespace std;
const int N = 1000100;
const int M = 500010<<1;
inline int read() {
int x = 0,f = 1;char v = getchar();
while (!isdigit(v)) {if (v =='-') f = -1;v = getchar();}
while (isdigit(v)) {x = x * 10 + v - 48;v = getchar();}
return x * f;
}
int f[N],n,m,ans;
struct node {
int a,b,c;
friend inline bool operator < (const node &rhs,const node &rs) {
return rhs.b*rs.c > rhs.c*rs.b;
}
}pre[N];
signed main() {
m = read(),n = read();
for (int i = 1;i <= n;++i) pre[i].a = read();
for (int i = 1;i <= n;++i) pre[i].b = read();
for (int i = 1;i <= n;++i) pre[i].c = read();
sort(pre+1,pre+1+n);
for (int i = 1;i <= n;++i) {
for (int j = m;j >= pre[i].c;--j) {
f[j] = max(f[j],f[j-pre[i].c] + (pre[i].a - j * pre[i].b));
}
}
for (int i = 1;i <= m;++i) {
ans = max(ans,f[i]);
}
printf("%lld",ans);
return 0;
}
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭