uva 10913 - Walking on a Grid(记忆化)

来源:互联网 发布:gt610数据 编辑:程序博客网 时间:2024/05/29 04:47
 

uva 10913 - Walking on a Grid(记忆化)

分类: UVA 算法竞赛-第九章 GRADE:C 动态规划-记忆化搜索 99人阅读 评论(0) 收藏 举报

题目链接:10913 - Walking on a Grid


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


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


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


[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. const int N = 80;  
  4. const int MAX = -200000000;  
  5. const int dir[3][2] = {{0, -1}, {0, 1}, {1, 0}};  
  6.   
  7. int n, k, vis[N][N], g[N][N];  
  8. long long dp[N][N][10][5], ans;  
  9.   
  10. void init() {  
  11.     ans = MAX;  
  12.     memset(vis, 0, sizeof(vis));  
  13.     for (int i = 1; i <= n; i++)  
  14.         for (int j = 1; j <= n; j++)  
  15.             for (int x = 0; x < 6; x++)  
  16.                 for (int y = 0; y < 3; y++)  
  17.                     dp[i][j][x][y] = MAX;  
  18.   
  19.     for (int i = 1; i <= n; i++)  
  20.         for (int j = 1; j <= n; j++)  
  21.             scanf("%d", &g[i][j]);  
  22.   
  23. }  
  24.   
  25. void dfs(int x, int y, int cnt, long long sum) {  
  26.     if (cnt > k) return ;  
  27.   
  28.     if (x == n && y == n) {  
  29.         if (sum > ans)  
  30.             ans = sum;  
  31.         return ;  
  32.     }  
  33.   
  34.     for (int i = 0; i < 3; i++) {  
  35.         int p = x + dir[i][0];  
  36.         int q = y + dir[i][1];  
  37.         if (p > 0 && p <= n && q > 0 && q <= n && vis[p][q] == 0) {  
  38.             vis[p][q] = 1;  
  39.             if (g[p][q] < 0 && dp[p][q][cnt + 1][i] < sum + g[p][q]) {  
  40.                 dp[p][q][cnt + 1][i] = sum + g[p][q];  
  41.                 dfs(p, q, cnt + 1, sum + g[p][q]);  
  42.             }  
  43.             else if (g[p][q] >= 0 && dp[p][q][cnt][i] < sum + g[p][q]) {  
  44.                 dp[p][q][cnt][i] = sum + g[p][q];  
  45.                 dfs(p, q, cnt, sum + g[p][q]);  
  46.             }  
  47.             vis[p][q] = 0;  
  48.         }  
  49.     }  
  50. }  
  51.   
  52. int main() {  
  53.     int t = 1;  
  54.     while (scanf("%d%d", &n, &k) == 2 &&  (n || k)) {  
  55.         init();  
  56.   
  57.         vis[1][1] = 1;  
  58.         if (g[1][1] >= 0)  
  59.             dfs(1, 1, 0, g[1][1]);  
  60.         else  
  61.             dfs(1, 1, 1, g[1][1]);  
  62.   
  63.         printf("Case %d: ", t++);  
  64.         if (ans != MAX)  
  65.             printf("%lld\n", ans);  
  66.         else  
  67.             printf("impossible\n");  
  68.     }  
  69.     return 0;  
  70. }