UVA 10913 - Walking on a Grid

来源:互联网 发布:西德尼谢尔顿 知乎 编辑:程序博客网 时间:2024/04/29 22:13

题目大意:从左上角走到右下角,只能向下,向左,向右走,同一个点不能走两次,要求走过负数点的次数有限,问走过的路径中所点点最大的是哪个?

分析: 1.最开始想用状压,但是状态压缩和解压都太麻烦,不可能实现。

2.问题中比较麻烦的是同一个点只能走一次的限制,在搜索的过程中采用一个bool数组,在状态表示时添加一维表示从哪个方向过来。

#include <iostream>#include <cmath>#include <cstdlib>#include <cstdio>#include <cstring>#include <string>#include <vector>#include <algorithm>#include <list>using namespace std;const long long INF = ((long long)1) << 60;int val[80][80];long long dp[80][80][6][3];bool visit_status[80][80][6][3];bool visit_grid[80][80];int ndict[3][2] = {0,-1,0,1,1,0};int n,max_nneg;bool read_input(){scanf("%d%d",&n,&max_nneg);if (n == 0 && max_nneg == 0){return false;}memset(visit_grid,false,sizeof(visit_grid));memset(visit_status,false,sizeof(visit_status));for (int i = 0 ; i < n ; ++i){for (int j = 0 ; j < n ; ++j){scanf("%d",&val[i][j]);}}return true;}bool is_valid(int i,int j,int neg){if (i < n && i >= 0 && j < n && j >= 0 && !visit_grid[i][j]){if (val[i][j] >= 0 || (val[i][j] < 0 && neg < max_nneg)){return true;}}return false;}long long get_max(int i,int j,int dic,int neg){bool& flag_status = visit_status[i][j][neg][dic];long long& sum = dp[i][j][neg][dic];if (flag_status){return sum;}if (i == n - 1 && j == n - 1){return val[i][j];}sum = -INF;flag_status = true;if (val[i][j] < 0){neg++;}for (int k = 0 ; k < 3 ; ++k){int ii = i + ndict[k][0];int jj = j + ndict[k][1];if (is_valid(ii,jj,neg)){visit_grid[ii][jj] = true;sum = max(sum,get_max(ii,jj,k,neg));visit_grid[ii][jj] = false;}}if (sum != -INF){sum += val[i][j];}return sum;}int main(){#ifdef shichunfreopen("test.in","r",stdin);freopen("test.out","w",stdout);#endifint nth = 1;while (read_input()){visit_grid[0][0] = true;long long ans = get_max(0,0,0,0);if (-INF == ans){printf("Case %d: impossible\n",nth++);}else{printf("Case %d: %lld\n",nth++,ans);}}return 0;}


0 0
原创粉丝点击