HDU-2686 Matrix(多线程DP?)2017寒假集训

题意:给一个矩阵,求(1,1)到(n,n)的两条路径(不能相交),求能取到的最大值

数据范围:2 <= n <= 30,矩阵上的数 < 100

思路:记得在kuangbin最短路专题里有个要求差不多的题,当时写不出来,查题解是最大流????

然后问了大佬,说这题也可以网络流做,不过呢。。。然后我就了解到了这个叫多线程DP的东西

多线程。。????这不是C语言的那啥玩意。。。吗?课设好像还要用呢orz

其实这里是指DP数组存分别在两个点的状态能走出多少的最大值,走的时候不走到一个点上就行了,用记忆化搜索写很方便很好理解就跟爆搜的差不多

用递推还可以省出一维的空间,设当前是第k步,每次从k-1转移过来,然后恒有x+y==k就可以只设三维的状态了

自己写的是记忆化,毕竟n只有30

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int mx = 35;
 7 int a[mx][mx], dp[mx][mx][mx][mx], n;
 8 int dr[] = {1, 0, 1, 0};
 9 int dc[] = {0, 1, 0, 1};
10 int du[] = {1, 1, 0, 0};
11 int dv[] = {0, 0, 1, 1};
12 
13 int dfs(int x, int y, int u, int v){
14     if (a[x][y] == -1 || a[u][v] == -1) return 0;
15     if (x+y == 2*n) return a[n][n];
16     if (dp[x][y][u][v] != -1) return dp[x][y][u][v];
17     if (x == u && y == v && x+y > 2) return 0;
18     int ans = 0;
19     for (int i = 0; i < 4; i++){
20         int dx = x + dr[i];
21         int dy = y + dc[i];
22         int r = u + du[i];
23         int c = v + dv[i];
24         ans = max(ans, dfs(dx, dy, r, c));
25     }
26     return dp[x][y][u][v] = ans+a[x][y]+a[u][v];
27 }
28 
29 int main(){
30     while (scanf("%d", &n) == 1){
31         memset(dp, -1, sizeof dp);
32         memset(a, -1, sizeof a);
33         for (int i = 1; i <= n; i++)
34             for (int j = 1; j <= n; j++)
35                 scanf("%d", &a[i][j]);
36         printf("%d\n", dfs(1, 1, 1, 1)-a[1][1]);
37     }
38     return 0;
39 }

 

posted @ 2018-05-14 12:18  QAQorz  阅读(122)  评论(0编辑  收藏  举报