[队内测试Day10.22T3][codevs1684]垃圾陷阱
来源:互联网 发布:月薪8000能招到java 编辑:程序博客网 时间:2024/06/06 06:45
题目←
考试的时候沉迷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;}
阅读全文
0 0
- [队内测试Day10.22T3][codevs1684]垃圾陷阱
- 垃圾陷阱codevs1684
- 【codevs1684】垃圾陷阱 解题报告
- [队内测试Day10.22T1][bzoj1821]部落划分 Group
- [队内测试Day10.22T4][洛谷P2680]运输计划
- [队内测试Day10.10]贪心+模拟+BFS
- [队内测试Day10.12]贪心+状压+分块+树状数组
- [队内测试Day10.26][P97]T1 字符串+前缀和
- [队内测试Day10.18]递推+tarjan+最小表示法+脑洞
- [队内测试Day10.24Final]逆序对+表达式计算+贪心+图论+数论?
- 垃圾陷阱
- 垃圾陷阱
- 2016.8.6测试解题报告(well-垃圾陷阱)
- java笔记--day10--内部类
- day10(匿名)内部类
- Day10 --包 匿名内部类
- 洛谷1156 垃圾陷阱
- 洛谷P1156 垃圾陷阱
- 高精度阶乘
- Mybatis中日志配置文件无效
- python3 正则表达式(更新中)
- <context:component-scan>使用说明
- 实验二 Linux用户管理
- [队内测试Day10.22T3][codevs1684]垃圾陷阱
- HDU1596 find the safest road(最短路)
- C++风格_引用参数
- [noip2015]信息传递 题解
- 英文投稿的状态
- 前端基础 JavaScript Data、Math对象 笔记
- 手把手用 IntelliJ IDEA 和 SBT 创建 scala 项目
- Python 第一节
- JVM原理之垃圾收集