UVA - 10913 Walking on a Grid

来源:互联网 发布:淘宝v任务 编辑:程序博客网 时间:2024/05/17 06:11

题目大意:给出n,k,然后给出一个n*n的图,从(1,1)通过向下,左和右三个方向,走到(n,n)点,途中不可以走相同的位置,并且路过的位置为负数的个数<= k, 找出一条路使得这条路上的值之和最大。不能到达输出impossible


解题思路:记忆化搜索,用四维数组去记录最优解,vis二维数组表示当前访问状态,dp[x][y][i][j]表示位置x,y的地方,当路过的负数个数为i且从j代表的方向进入时的最优解。


我写完的时候超时了,但是改了一下方向就过了,估计是方向的缘故将最优解记录住了,所以优化比较大。


#include <cstring>#include <cstdio>#include <algorithm>#include <climits>using namespace std;long long DP[80][80][7][3];int vis[80][80][7][3], mat[80][80], n;bool judge(int a) {return a >= 0 && a < n;}long long DPS(int x, int y, int k, int d) {long long &m = DP[x][y][k][d];if (vis[x][y][k][d])return m;vis[x][y][k][d] = true;if (k == 0 && mat[x][y] < 0)return INT_MIN;if (x == n-1 && y == n-1)return m = mat[x][y];if (mat[x][y] < 0)k--;int r, c;if (d != 1) {r = x, c = y + 1;if (judge(c) && DPS(r, c, k, 0) != INT_MIN)m = max(m, DP[r][c][k][0] + mat[x][y]);}if (d != 0 && x != n - 1) {r = x, c = y - 1;if (judge(c) && DPS(r, c, k, 1) != INT_MIN)m = max(m, DP[r][c][k][1] + mat[x][y]);}if (x != n - 1) {r = x + 1, c = y;if (DPS(r, c, k, 2) != INT_MIN)m = max(m, DP[r][c][k][2] + mat[x][y]);}return m;}int main() {int kase = 0, k;while (scanf("%d%d", &n, &k), n) {for (int i = 0; i < n; i++)for (int j = 0; j < n; j++) {scanf("%d", &mat[i][j]);for (int l = 0; l <= k; l++ )DP[i][j][l][0] = DP[i][j][l][1] = DP[i][j][l][2] = INT_MIN;}memset(vis, 0, sizeof(vis));printf("Case %d: ", ++kase);if (DPS(0, 0, k, 0) != INT_MIN)printf("%lld\n", DPS(0, 0, k, 0));elseprintf("impossible\n");}return 0;}


0 0
原创粉丝点击