hdu_round1-1004 离开迷宫(dp)

记录一个菜逼的成长。。web

离开迷宫数组

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

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

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

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

Sample Input
3 3 4
1 2 9
2 6 2
3 2 1
1 1 1
0 1 0
0 0 1code

Sample Output
1 12orm

dp[i][j][k]:=(i,j)k
有以下转移:
dp[i][j][k]=max(dp[i1][j][k+b[i][j]]+a[i][j],dp[i][j][k])(k+b[i][j]x)
dp[i][j][k]=max(dp[i][j1][k+b[i][j]]+a[i][j],dp[i][j][k])(k+b[i][j]x) xml

dp数组初始化-1
只有当上一个状态不为-1才能转移到当前状态。。(话说好几回忘记加了ip

#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;
}