洛谷1417 烹调方案 dp 贪心
来源:互联网 发布:大众软件停刊 编辑:程序博客网 时间:2024/04/30 12:00
洛谷 1417 dp
传送门
挺有趣的一道dp题目,看上去接近于0/1背包,但是考虑到取每个点时间不同会对最后结果产生影响,因此需要进行预处理
对于物品x和物品y,当时间为p时,先加x后加y的收益为
a[x]-(p+c[x])*b[x]+a[y]-(p+c[x]+c[y])*by
而先加y再加x的收益为
a[y]-(p+c[y])*b[y]+a[x]-(p+c[y]+c[x])*bx
化简这两个式子,不难发现对于x和y,如果满足
c[x]*b[y]<c[y]*b[x]
,那么x 一定优于 y
由以上推论即可得解,对于题目中所给的物品,将其按照以上顺序排序,在进行0/1背包,即可得解
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 100000 + 100;struct data { long long ai, bi, ci;};data p[60];long long dp[maxn];int t, n;bool cmp(data aa, data bb) { return (aa.ci * bb.bi < aa.bi * bb.ci);}int main () { scanf("%d %d", &t, &n); for (int i = 1; i <= n; i++) scanf("%lld", &p[i].ai); for (int i = 1; i <= n; i++) scanf("%lld", &p[i].bi); for (int i = 1; i <= n; i++) scanf("%lld", &p[i].ci); std :: sort(p + 1, p + n + 1, cmp); for (int i = 1; i <= n; i++) for (int j = t; j >= p[i].ci; j--) dp[j] = std :: max(dp[j], dp[j - p[i].ci] + (p[i].ai - j * p[i].bi)); long long ans = 0; for (int i = 1; i <= t; i++) ans = std :: max(ans, dp[i]); printf("%lld", ans); return 0;}
当时做这题时想尝试多次贪心取最优值的办法,,然而,最后只得了30分,虽然尝试未成功,但是面对贪心题目时,这也不失为一种方法
附上乱搞代码
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 50 + 10;int T, n;struct data { int ai; int bi; int ci;};data p[maxn];int dp[100000 + 10];bool cmp1(data aa, data bb) { return(aa.bi < bb.bi);}bool cmp2(data aa, data bb) { return (aa.ci < bb.ci);}bool cmp3(data aa, data bb) { return (aa.ai > bb.ai);}bool cmp4(data aa, data bb) { return (aa.bi * aa.ci < bb.bi * bb.ci);}int main () { scanf("%d %d", &T, &n); for (int i = 1; i <= n; i++) scanf("%d", &p[i].ai); for (int i = 1; i <= n; i++) scanf("%d", &p[i].bi); for (int i = 1; i <= n; i++) scanf("%d", &p[i].ci); int ans = 0; for (int i = 1; i <= n; i++) { for (int j = T; j >= p[i].ci; j--) { dp[j] = std :: max(dp[j],dp[j - p[i].ci] + (p[i].ai - j * p[i].bi)); } } for (int i = 1; i <= T; i++) ans = std :: max(ans, dp[i]); std :: sort(p + 1, p + n + 1, cmp1); memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; i++) { for (int j = T; j >= p[i].ci; j--) { dp[j] = std :: max(dp[j],dp[j - p[i].ci] + (p[i].ai - j * p[i].bi)); } } for (int i = 1; i <= T; i++) ans = std :: max(ans, dp[i]); std :: sort(p + 1, p + n + 1, cmp2); memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; i++) { for (int j = T; j >= p[i].ci; j--) { dp[j] = std :: max(dp[j],dp[j - p[i].ci] + (p[i].ai - j * p[i].bi)); } } for (int i = 1; i <= T; i++) ans = std :: max(ans, dp[i]); std :: sort(p + 1, p + n + 1, cmp3); memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; i++) { for (int j = T; j >= p[i].ci; j--) { dp[j] = std :: max(dp[j],dp[j - p[i].ci] + (p[i].ai - j * p[i].bi)); } } for (int i = 1; i <= T; i++) ans = std :: max(ans, dp[i]); std :: sort(p + 1, p + n + 1, cmp4); memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; i++) { for (int j = T; j >= p[i].ci; j--) { dp[j] = std :: max(dp[j],dp[j - p[i].ci] + (p[i].ai - j * p[i].bi)); } } for (int i = 1; i <= T; i++) ans = std :: max(ans, dp[i]); printf("%d", ans); return 0;}
1 0
- 洛谷1417 烹调方案 dp 贪心
- 洛谷1417 烹调方案
- 洛谷 P1417 烹调方案
- 洛谷 P1417 烹调方案
- 洛谷 P1417 烹调方案
- 洛谷 P1417 烹调方案
- 洛谷 P1417 烹调方案
- 洛谷 1417——烹调方案【动规】
- 烹调方案
- P1417 烹调方案
- P1417 烹调方案
- 【动态规划】[luoguP1417]烹调方案
- 烹调常识
- 洛谷P1654 产品排序:贪心+DP
- qbxt Day3 DP+DP+贪心
- hdu 1257 dp+贪心
- HDU 1257 DP + 贪心
- 【贪心DP】过河问题
- 2016 10 27 考试 dp 向量 乱搞
- Eclipse常用快捷键汇总
- 2016 10 28考试 dp 乱搞 树状数组
- 洛谷1387 二维dp 不是特别简略的题解 智商题
- 木讷的程序员需要知道的事情 (二)
- 洛谷1417 烹调方案 dp 贪心
- 详解C中volatile关键字
- 使用scrapy爬取网站上的所有图片
- if __name__== "__main__" 的意思(作用)python代码复用
- c#中的类型转换
- 洛谷1199 简单博弈 贪心
- 洛谷 2409 dp 月赛题目
- c++设计模式之享元模式
- 洛谷 1063 dp 区间dp