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 }