hdu—1004

来源:互联网 发布:核聚变发电 知乎 编辑:程序博客网 时间:2024/06/05 19:57

离开迷宫

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 0    Accepted Submission(s): 0


Problem Description
yyf是一个日理万机的男人,但自从最近他勾搭上了女神之后便随叫随到,以至于荒废了很多事情。这天,yyf正在探索一个充满陷阱的古代迷宫,他的女神来电话了,由于离迷宫出口太远了,可能要花很多时间才能回去,所以yyf不打算原路返回,而是挥动他那强壮有力的右手砸开墙壁直接走向出口。已知yyf在(1,1)的位置,而出口在(N,M)的位置,yyf每次只会向下或向右走。
而同时又由于事发突然,yyf没能给女神准备礼物,于是他决定在回去的路上尽量多拿点迷宫里的财宝作为礼物。当然,古代的迷宫里少不了陷阱,虽然yyf实在太强了而导致所有的陷阱只能对他的装备造成1点的耐久损失,但由于yyf本来只是打算探索迷宫,所以并没有准备太好的装备,最初的耐久值仅为x,而如果装备破破烂烂的走到女神那边是非常有失风度的。所以yyf想要知道自己能否在保证最快离开迷宫的同时装备不被破坏(耐久=0时装备会破破烂烂哦),如果可以,他希望能带走尽量多的财宝,如果不行,他就只能在离开迷宫后回趟家带上自己最好的衣服和专门为女神准备的礼物了。
给你迷宫里分布着的财宝信息以及陷阱布置。yyf希望知道自己在保证装备不变成破破烂烂的情况下最多能拿多少的财宝,如果出现多个方案,yyf希望自己的装备能尽量少被陷阱打中。
 

Input
第一行:迷宫的大小N和M以及yyf的装备的耐久x 
接下来2N行
前N行每行M个整数(),表示迷宫里(i,j)位置的财宝价值
后N行每行M个数字0或1,表示迷宫里(i,j)位置是否有陷阱(1为有)
(0<=N,M,x<=100)
 

Output
若有可行方案,输出在获得最大价值的情况下装备能留有的最大耐久度与可获得的财宝的最大价值。若无可行方案,则输出-1。
 

Sample Input
3 3 41 2 92 6 23 2 11 1 10 1 00 0 1
 

Sample Output
1 12
 

【分析】
基础三维dp,数据非常小所以三维直接开就好了...
f[i][j][k]表示到达点(i,j)时装备耐久度为k的获得财宝的最大价值,所以状态转移就是:
f[i+1][j][k-b[i+1][j]]=max(f[i+1][j][k-b[i+1][j]],f[i][j][k]+a[i+1][j]);(k-b[i+1][j]>0)
f[i][j+1][k-b[i][j+1]]=max(f[i][j+1][k-b[i][j+1]],f[i][j][k]+a[i][j+1]);(
k-b[i][j+1]>0)
//都不知道自己一开始在想什么东西....放了一会回过头来想直接1Y了...
【代码】
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;int n,m,X;int a[120][120];int b[120][120];int f[120][120][120];int main(){    while (~scanf("%d%d%d",&n,&m,&X))    {        for (int i=0;i<n;i++) for (int j=0;j<m;j++) scanf("%d",&a[i][j]);        for (int i=0;i<n;i++) for (int j=0;j<m;j++) scanf("%d",&b[i][j]);        memset(f,-1,sizeof(f));        f[0][0][X-b[0][0]]=a[0][0];        for (int i=0;i<n;i++)            for (int j=0;j<m;j++)                for (int k=1;k<=X;k++)                    if (f[i][j][k]!=-1)                    {                        if (i+1<n&&k-b[i+1][j]>0)                            f[i+1][j][k-b[i+1][j]]=max(f[i+1][j][k-b[i+1][j]],f[i][j][k]+a[i+1][j]);                        if (j+1<m&&k-b[i][j+1]>0)                            f[i][j+1][k-b[i][j+1]]=max(f[i][j+1][k-b[i][j+1]],f[i][j][k]+a[i][j+1]);                    }        int ans=-1;        int now=-1;        for (int i=X;i>=1;i--)            if (f[n-1][m-1][i]>ans) ans=f[n-1][m-1][i],now=i;                if (ans!=-1)            printf("%d %d\n",now,ans);        else puts("-1");    }    return 0;}


原创粉丝点击