uva10913(dp + 回溯)

题目的意思就是要从(1,1)那个格子走到(n,n)那个格子.并且途中只能经过k个负数.

而且走的时候方向不能向上,其他方向都可以,还有走过的点不能再走.问路上经过的点的值加起来最大是多少,如果走不到就输出impossible;

用来记忆的f数组要开四维,记录位置(x,y),经过的负数的个数,还有方向,刚开始没有考虑方向,错了很多发,因为就算同一个位置,经过同样多的负数,如果方向不同,也是不一样的状态:

然后直接一步步回溯就行了.需要注意的是,之前的从左边过来,现在就不能在回左边去,之前从右边过来,现在就不能再回右边去.


AC代码;


#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define ll long long
const int INF = -0x3f3f3f3f;
const ll N = 80;
ll f[N][N][7][5];
int dir[3][2] = {{0,1} ,{1,0} ,{0 ,-1}};
ll grid[N][N];
int vis[N][N][7][5];
int viss[N][N];
int n,k;
ll dp(ll x, ll y , ll t,ll d) {
	ll& ans = f[x][y][t][d];
	if(vis[x][y][t][d])
		return ans;
	if(t == 0) {
		vis[x][y][t][d] = 1;
		return ans = INF;
	}
	if(x == n && y == n) {
		vis[x][y][t][d] = 1;
		return ans = grid[x][y];
	}
	ans = INF;
	for(int i = 0 ; i < 3 ;i++) {
		int nx = x + dir[i][0];
		int ny = y + dir[i][1];
		if(d != 1 & d + i == 2)
			continue;
		if(nx >= 1 && ny >= 1 && nx <= n && ny <= n && !viss[nx][ny]) {
			viss[nx][ny] = 1;
			if(grid[x][y] < 0) {
				ll temp = dp(nx,ny,t - 1 , i);
				if(temp != INF)
					ans = max(ans , temp + grid[x][y]);
			}
			else {
				ll temp = dp(nx,ny,t , i);
				if(temp != INF)
					ans = max(ans ,temp + grid[x][y]);
			}
			viss[nx][ny] = 0;
		}
	}
	vis[x][y][t][d] = 1;
	return ans;
}
int main () {
	int cas = 1;
	while(scanf("%d%d",&n,&k) && (n + k)) {
		memset(vis , 0 ,sizeof(vis));
		memset(viss , 0 ,sizeof(viss));
		for(int i = 1 ; i<= n ; i++) {
			for (int j = 1 ; j <= n ; j++) {
				scanf("%lld",&grid[i][j]);
			}
		}
		if(grid[n][n] >= 0)
			k++;
		ll res = dp(1,1,k,1);
		if(res == INF) 
			printf("Case %d: impossible\n",cas++);
		else
			printf("Case %d: %lld\n",cas++ , res);
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值