您的位置:首页 > 其它

uva_10913 - Walking on a Grid( 普通DP )

2012-12-15 13:41 323 查看
想对了状态,结果超时,原来还需要另外一个数组标记是否访问过的
状态: dp[x][y][k][d] 表示到大(x,y)最多踏上k个负数方格且由前一个经过d的方向过来的
状态转移: dp[x][y][k][d] = max(dp[x][y][k'][d']) 保证 d'不与d相对,k根据当前方格的数值而定

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define DIM     2
#define DIR     3
#define MAXK    6
#define MAXN    76

int n, val[MAXN][MAXN], visit[MAXN][MAXN][MAXK][DIR];
int dir[][DIM] = {
{0, -1}, {0, 1}, {1, 0}
};
long long dp[MAXN][MAXN][MAXK][DIR], INF;

long long dfs(int x, int y, int k, int d)
{
int cur_k( k );
cur_k -= ((val[x][y] < 0)? 1 : 0);
if( cur_k < 0 ) {
return INF;
}
if( visit[x][y][k][d] ) {
return dp[x][y][k][d];
}
if( x == n && y == n ) {
visit[x][y][k][d] = 1;
return dp[x][y][k][d] = val[x][y];
}
int tx, ty;
long long rst(INF);
for(int i = 0; i < DIR; i ++) {
if( 1 == (d+i) ) {
continue;
}
tx = x+dir[i][0]; ty = y+dir[i][1];
if( tx < 1 || ty < 1 || tx > n || ty > n )  {
continue;
}
if( INF != dfs(tx, ty, cur_k, i) ) {
rst = max(rst, val[x][y]+dp[tx][ty][cur_k][i]);
}
}
visit[x][y][k][d] = 1;
return dp[x][y][k][d] = rst;
}

int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
long long rst;
int cas(1), max_k, x, y;
while( scanf("%d %d", &n, &max_k) ) {
if( !n && !max_k ) {
break;
}
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= n; j ++) {
scanf("%d", &val[i][j]);
}
}
if( 1 == n && max_k < 0 ) {
printf("Case %d: impossible\n", cas ++); continue;
}
if( 1 == n ) {
printf("Case %d: %d\n", cas ++, val[1][1]); continue;
}
memset(visit, 0, sizeof(visit));
memset(dp, -0x3F, sizeof(dp)); rst = INF = dp[0][0][0][0];
if( INF != dfs(1, 1, max_k, 1) ) {
rst = max(rst, dfs(1, 1, max_k, 1));
}
if( INF != rst ) {
printf("Case %d: %lld\n", cas ++, rst); continue;
}
printf("Case %d: impossible\n", cas ++);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: