ZCMU—1601
2016-12-30 05:40
183 查看
1601: 卡斯丁狗去挖矿
Time Limit: 3 Sec Memory Limit: 128 MB[Submit][Status][Web
Board]
Description
最近卡斯丁狗和他的好基友Tomcat在玩《我的世界》这款游戏。在游戏中玩家可以用各种材料搭建房屋,制造铁路线,制造炸弹,晚上还可以打僵尸等等。然而在这之前最最重要的就是挖矿。这天卡斯丁狗背着一个最多能装重量为 n 的背包去矿洞里挖矿。从洞口看矿洞是一个深度为d等腰RT超级赛亚三角形,每个坐标点都有矿(如图)。洞口在三角形的最顶端,坐标为(1,1)。由于卡斯丁狗开挂,他只想从坐标为(x,y)的点走到坐标为(x+1,y)或者(x+1,y+1)的点,并且每经过一个点他可以选着挖或者不挖这个点的矿。问卡斯丁狗最多能背多少矿回家。Input
第一行输入n,d。接下来d行第i行输入i个数,表示矿的重量。
输入为小于300大于0。
Output
输出最大能带走的矿。Sample Input
100 399
1 99
100 1 44
Sample Output
100【分析】
本质上还是01背包....其实一眼就可以看出来的,只是在01背包的基础上增加了一个移动路径,所以给人一种需要bfs搜索路径后dp的错觉....当然bfs也是没问题的。但其实...不用考虑那么多三维dp直接做就可以了,因为数据不大只有300 , 300*300*300*4/1024/1024≈102MB
所以直接干就行了...
f[i][j][k]表示到坐标(i,j)背包使用量为k时的最大价值,对于矿石,价格和体积都是a[i][j]
那么当前状态可以从f[i-1][j][k],f[i-1][j-1][k],f[i-1][j][k-a[i][j]],f[i-1][j-1][k-a[i][j]]四个状态移动过来
状态转移方程:f[i][j][k]=max(max(f[i-1][j][k],f[i-1][j-1][k]),max(f[i-1][j][k-a[i][j]]+a[i][j],f[i-1][j-1][k-a[i][j]]+a[i][j]));
显然方程虽然长,但是并没有什么特殊的地方... 就是一个三维的01背包...多了一个坐标限制条件罢了,因为限制了坐标,所以无所谓k正着还是反着~
(PS.这里我为了省内存所以没有读取a[i][j],因为a[i][j]的时效性只有一次,所以重复读取进一个变量也可以)
【代码】
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int f[310][310][310]; int main() { int n,m,x; while (~scanf("%d%d",&m,&n)) { memset(f,0,sizeof(f)); int ans=0; //for (int i=1;i<=n;i++) for (int j=1;j<=i;j++) scanf("%d",&a[i][j]); for (int i=1;i<=n;i++) for (int j=1;j<=i;j++) { scanf("%d",&x); for (int k=x;k<=m;k++) { f[i][j][k]=max(max(f[i-1][j][k],f[i-1][j-1][k]),max(f[i-1][j][k-x]+x,f[i-1][j-1][k-x]+x)); ans=max(ans,f[i][j][k]); } } printf("%d\n",ans); } }
相关文章推荐
- hust1601 校赛
- [Bzoj1601][Usaco2008 Oct]灌水
- c++_primer_exercise_1601_1604
- BZOJ 1601: [Usaco2008 Oct]灌水( MST )
- UVa 1601 例题7-9 万圣节后的早晨
- bzoj1601【Usaco2008 Oct】灌水
- UVa 1601 The morning after Halloween(单向BFS+双向BFS)
- zcmu1691
- ZCMU1551
- Atitit 发帖机实现(4 )- usbQBM1601 gui操作标准化规范与解决方案attilax总结
- ZCMU—1478
- ZCMU—1127
- ZCMU----1779
- ZCMU-1658
- ZCMU-1750
- ZCMU—1455
- ZCMU-1774-最短的串
- ZCMU-1675-三角形面积
- ZCMU-1540-第K大个数
- 例题7-9 万圣节后的早晨 UVa1601