1. 程式人生 > >HDU-2686 Matrix(多線程DP?)2017寒假集訓

HDU-2686 Matrix(多線程DP?)2017寒假集訓

範圍 多線程dp 多少 數組 while set n) code names

題意:給一個矩陣,求(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 }

HDU-2686 Matrix(多線程DP?)2017寒假集訓