[队内测试Day10.22T3][codevs1684]垃圾陷阱
2017-10-22 17:19
447 查看
题目←
考试的时候沉迷T4而忽略掉的DP题
也是该复习DP了……
摸鱼:
设dp[i][j]为第i个物品在时间为j时的最大高度
转移更直观一些
dp[i][j] = dp[i - 1][j - l[i].t];//吃
dp[i][j] = dp[i - 1][j] + l[i].h//堆
注意在吃的时候,需要满足j - l[i].t >= l[i].f,堆得话需满足j >= l[i].f
意义为在使用了i - 1堆垃圾而到达第i堆垃圾扔下的时间的情况,这样才是合法的
正解:
如果不看题解是没有这种思路的……
充分体现了DP的另一个技巧:设计不出方程的时候把数组下标和它存的内容换一换
设f[j]为到达高度i时的最大生命时间
对于垃圾i,有吃和堆的情况:
f[j + l[i].h] = max(f[j + l[i].h],f[j]);//堆,高度增时间不增
f[j] += l[i].w //吃,吃掉时一定为这一高度的最优情况
关于垃圾到达时间的限制,仅当f[j] >= 垃圾i的到达时间时,才可以选择堆或吃
否则为i之前的垃圾无法在i到来的时刻堆到高度j,该高度不合法。
如果无法到达则全部吃掉可存活最长时间,输出f[0]
确实有点像带限制的01背包?
考试的时候沉迷T4而忽略掉的DP题
也是该复习DP了……
摸鱼:
设dp[i][j]为第i个物品在时间为j时的最大高度
转移更直观一些
dp[i][j] = dp[i - 1][j - l[i].t];//吃
dp[i][j] = dp[i - 1][j] + l[i].h//堆
注意在吃的时候,需要满足j - l[i].t >= l[i].f,堆得话需满足j >= l[i].f
意义为在使用了i - 1堆垃圾而到达第i堆垃圾扔下的时间的情况,这样才是合法的
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 20000 + 50; struct edge{ int f,t,h; }l[MAXN << 1]; int D,G,dp[105][MAXN],lim; bool cmp(edge a,edge b){ return a.f < b.f; } int main(){ scanf("%d%d",&D,&G); for(int i = 1;i <= G;i ++){ scanf("%d%d%d",&l[i].f,&l[i].t,&l[i].h); } sort(l + 1,l + G + 1,cmp); memset(dp,-1,sizeof(dp)); for(int i = 0;i <= 10;i ++){ dp[0][i] = 0; } lim = 10; for(int i = 1;i <= G;i ++){ if(lim < l[i].f){ printf("%d",lim); return 0; } lim += l[i].t; for(int j = 0;j <= lim;j ++){ dp[i][j] = dp[i - 1][j]; if(j >= l[i].f){ if(j - l[i].t >= l[i].f)dp[i][j] = max(dp[i][j],dp[i - 1][j - l[i].t]); if(dp[i - 1][j] != -1) dp[i][j] = max(dp[i][j],dp[i - 1][j] + l[i].h); if(dp[i][j] >= D){ printf("%d\n",l[i].f); return 0; } } } } /*for(int i = 1;i <= G;i ++){ for(int j = 0;j <= lim;j ++){ printf("%d ",dp[i][j]); } printf("\n"); }*/ printf("%d",lim); return 0; }
正解:
如果不看题解是没有这种思路的……
充分体现了DP的另一个技巧:设计不出方程的时候把数组下标和它存的内容换一换
设f[j]为到达高度i时的最大生命时间
对于垃圾i,有吃和堆的情况:
f[j + l[i].h] = max(f[j + l[i].h],f[j]);//堆,高度增时间不增
f[j] += l[i].w //吃,吃掉时一定为这一高度的最优情况
关于垃圾到达时间的限制,仅当f[j] >= 垃圾i的到达时间时,才可以选择堆或吃
否则为i之前的垃圾无法在i到来的时刻堆到高度j,该高度不合法。
如果无法到达则全部吃掉可存活最长时间,输出f[0]
确实有点像带限制的01背包?
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; int D,n; struct edge{ int f,h,w; }l[23333]; int f[233333]; int solve(){ f[0] = 10; for(int i = 1;i <= n;i ++){ for(int j = D;j >= 0;j --){ if(l[i].f <= f[j]){ f[j + l[i].h] = max(f[j + l[i].h],f[j]); if(j + l[i].h >= D)return l[i].f; f[j] += l[i].w; } } } return -1; } bool cmp(edge a,edge b){ return a.f < b.f; } int main(){ scanf("%d%d",&D,&n); for(int i = 1;i <= n;i ++){ scanf("%d%d%d",&l[i].f,&l[i].w,&l[i].h); } sort(l + 1,l + n + 1,cmp); int temp = solve(); if(temp == -1)temp = f[0]; printf("%d",temp); return 0; }
相关文章推荐
- 【codevs1684】垃圾陷阱 解题报告
- 垃圾陷阱codevs1684
- <背包DP>codevs 1684 垃圾陷阱
- 编辑器性能测试:Atom 、VS Code、Sublime Text
- [codevs3862]竞赛班的垃圾处理(刷水) 没写的少年去倒垃圾吧
- Miller-Rabin随机性素数测试方法 & [CodeVS 1702] 素数判定2
- 【codevs 1684】垃圾陷阱
- Codevs 1684 垃圾陷阱
- 2016.8.6测试解题报告(well-垃圾陷阱)
- codevs 2610 活动选择(贪心)(测试数据有错)
- CODE【VS】2849 素数判定 3(米勒拉宾素数测试的方法)
- 1684 垃圾陷阱
- Code UI Automation脱离VS黑盒自动化测试工具编写
- C#借助Code UI Automation脱离VS黑盒自动化测试工具编写
- [codevs3862]竞赛班的垃圾处理
- VSCode配置C++编写环境
- 【codevs3304】 水果姐逛水果街Ⅰ——杨子曰题目
- 【VSCode】Windows下VSCode编译调试c/c++【更新】
- codevs 1282 约瑟夫问题
- VS 2010 测试功能学习(17) – Feature Pack 2 正式发布(转)