记录一个菜逼的成长。。
离开迷宫
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 124 Accepted Submission(s): 30
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 4
1 2 9
2 6 2
3 2 1
1 1 1
0 1 0
0 0 1
Sample Output
1 12
dp[i][j][k]:=表示在(i,j)点耐久为k的最大价值
有如下转移:
dp[i][j][k]=max(dp[i−1][j][k+b[i][j]]+a[i][j],dp[i][j][k])(k+b[i][j]≤x)
dp[i][j][k]=max(dp[i][j−1][k+b[i][j]]+a[i][j],dp[i][j][k])(k+b[i][j]≤x)
dp数组初始化-1
只有当上一个状态不为-1才能转移到当前状态。。(话说好几次忘记加了
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
const int maxn = 100 + 10;
int a[maxn][maxn],b[maxn][maxn];
int dp[maxn][maxn][maxn];
int main()
{
int n,m,x;
while(~scanf("%d%d%d",&n,&m,&x)){
for( int i = 1; i <= n; i++ ){
for( int j = 1; j <= m; j++ ){
scanf("%d",&a[i][j]);
}
}
for( int i = 1; i <= n; i++ ){
for( int j = 1; j <= m; j++ ){
scanf("%d",&b[i][j]);
}
}
cl(dp,-1);
dp[1][1][x-b[1][1]] = a[1][1];
for( int i = 1; i <= n; i++ ){
for( int j = 1; j <= m; j++ ){
for( int k = 1; k <= x; k++ ){
if(i-1 > 0 && dp[i-1][j][k+b[i][j]] != -1 && k + b[i][j] <= x)
dp[i][j][k] = max(dp[i-1][j][k+b[i][j]] + a[i][j],dp[i][j][k]);
if(j-1 > 0 && dp[i][j-1][k+b[i][j]] != -1 && k + b[i][j] <= x)
dp[i][j][k] = max(dp[i][j-1][k+b[i][j]] + a[i][j],dp[i][j][k]);
}
}
}
int ans = -1,pos;
for( int i = 1; i <= x; i++ ){
if(ans < dp[n][m][i]){
ans = dp[n][m][i];
pos = i;
}
}
if(ans != -1)printf("%d %d\n",pos,ans);
else puts("-1");
}
return 0;
}