Uva--10913(动规,记忆化搜索,多维度)

2014-08-25 00:43:21

思路:本来想用递推式写的,写了半天还是WA,原因在于方向,这题和以前hdu写的走迷宫(只能右 / 下方向)凑最大点数那题不同,这题左右都可以走,而且又规定一个格子不能走两遍,所以普通递推DP是难以知道这个状态是从哪个方向转移来的,如果从右边转移来的,那么接下来右边就不能走了(左边同理)。

以为了方便,这题直接用记忆化搜索解,dp[i][j][k][dir] 表示用[i,j]这个点到终点经过k次负权格子,且状态是从dir方向转移来的最大路径和。

(后来想想,如果在普通递推DP中加上方向维度,可能也可行,呵呵)

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cmath>
 5 using namespace std;
 6 const int INF = 1 << 30;
 7 typedef long long ll;
 8 
 9 int n,k;
10 int g[80][80];
11 ll dp[80][80][6][5];
12 int caled[80][80][6][5];
13 int vis[80][80];
14 int Case = 0;
15 
16 ll Dfs(int x,int y,int cnt,int dir){
17     ll &res = dp[x][y][cnt][dir];
18     if(g[x][y] < 0){
19         cnt++;
20         if(cnt > k){
21             return -INF;
22         }
23     }
24     if(x == 1 && y == 1){
25         return res = g[x][y];
26     }
27     if(caled[x][y][cnt][dir]){
28         return res;
29     }
30     caled[x][y][cnt][dir] = 1;
31     res = -INF;
32     vis[x][y] = 1;
33     ll tem;
34     if(y > 1 && !vis[x][y - 1]){
35         if((tem = Dfs(x,y - 1,cnt,4)) != -INF){
36             res = max(res,tem + g[x][y]);
37         }
38     }
39     if(y < n && !vis[x][y + 1]){
40         if((tem = Dfs(x,y + 1,cnt,2)) != -INF){
41             res = max(res,tem + g[x][y]);
42         }
43     }
44     if(x > 1 && !vis[x - 1][y]){
45         if((tem = Dfs(x - 1,y,cnt,1)) != -INF){
46             res = max(res,tem + g[x][y]);
47         }
48     }
49     vis[x][y] = 0;
50     //printf("dp[%d][%d][%d] : %d\n",x,y,cnt,res);
51     return res;
52 }
53 
54 int main(){
55     //freopen("in.txt","r",stdin);
56     while(scanf("%d%d",&n,&k) == 2 && (n || k)){
57         for(int i = 1; i <= n; ++i){
58             for(int j = 1; j <= n; ++j){
59                 scanf("%d",&g[i][j]);
60             }
61         }
62         memset(vis,0,sizeof(vis));
63         memset(caled,0,sizeof(caled));
64         ll ans = Dfs(n,n,0,1);
65         printf("Case %d: ",++Case);
66         if(ans == -INF){
67             printf("impossible\n");
68         }
69         else{
70             printf("%lld\n",ans);
71         }
72     }
73     return 0;
74 }

 

转载于:https://www.cnblogs.com/naturepengchen/articles/3933967.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值