nyoj 61(双线程dp)
生活随笔
收集整理的這篇文章主要介紹了
nyoj 61(双线程dp)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述:
? ?在一個矩陣內找出兩條從1,1到m,n的路徑(一條從1,1 到 m,n 一條 從m,n到1,1),并且路徑之上的權值之和最大。
解題思路:這道題目如果是想從(1,1)->(n,m),再從(n,m)->(1,1)那樣肯定會想不清楚。比較好的辦法就是看成有兩條路從(1,1)->(n,m),這樣就可以定義狀態?F[i][j][k][l]=max{F[i-1][j][k-1][l],F[i-1][j][k][l-1],F[i][j+1][k-1][l],F[i][j+1][k][l-1]}+a[i][j]+a[k][l].
含義:當一張紙條傳到i,j 另一張傳到k,l時路徑上權值的最大值。
這里需要考慮到一個問題,兩條路會不會有重疊的地方,其實是不會的,因為我們首先控制i,j,k,l不會相等,也就是不會交于同一點,其次,我們在遞推時,是兩條路一起走的,不存在哪條路先走,這樣就可以保證兩條路的一致性。
仔細觀察很容易得到一個這樣的結論 紙條傳的橫坐標+縱坐標=走的步數; 通過這個結論便很簡單的消維。
參考博客:http://blog.csdn.net/zy691357966/article/details/7795365
#include<iostream> #include<cstdio> #include<cstring> using namespace std;const int maxn = 55; int n,m; int map[maxn][maxn],dp[maxn<<1][maxn][maxn];int Max(int a,int b,int c,int d) {if(a >= b && a >= c && a >= d) return a;if(b >= a && b >= c && b >= d) return b;if(c >= a && c >= b && c >= d) return c;if(d >= a && d >= b && d >= c) return d; }int main() {int t;cin >> t;while(t--){cin >> n >> m;for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)cin >> map[i][j];memset(dp,0,sizeof(dp));for(int k = 1; k <= n + m - 2; k++)for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++){if(i == n && j == n && k == n + m - 2)dp[k][i][j] = Max(dp[k-1][i][j],dp[k-1][i-1][j],dp[k-1][i][j-1],dp[k-1][i-1][j-1]) + map[i][k+2-i] + map[j][k+2-j];else if(i != j && k + 2 - i >= 1 && k + 2 - j >= 1)dp[k][i][j] = Max(dp[k-1][i][j],dp[k-1][i-1][j],dp[k-1][i][j-1],dp[k-1][i-1][j-1]) + map[i][k+2-i] + map[j][k+2-j];}printf("%d\n",dp[n+m-2][n][n]);}return 0; }
總結
以上是生活随笔為你收集整理的nyoj 61(双线程dp)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【JEECG技术博文】jeecg 定时任
- 下一篇: 微信公众帐号开发教程第15篇-自定义菜单