nyoj 61(双线程dp)
? ?在一個(gè)矩陣內(nèi)找出兩條從1,1到m,n的路徑(一條從1,1 到 m,n 一條 從m,n到1,1),并且路徑之上的權(quán)值之和最大。
解題思路:這道題目如果是想從(1,1)->(n,m),再?gòu)?n,m)->(1,1)那樣肯定會(huì)想不清楚。比較好的辦法就是看成有兩條路從(1,1)->(n,m),這樣就可以定義狀態(tài)?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].
含義:當(dāng)一張紙條傳到i,j 另一張傳到k,l時(shí)路徑上權(quán)值的最大值。
這里需要考慮到一個(gè)問題,兩條路會(huì)不會(huì)有重疊的地方,其實(shí)是不會(huì)的,因?yàn)槲覀兪紫瓤刂苅,j,k,l不會(huì)相等,也就是不會(huì)交于同一點(diǎn),其次,我們?cè)谶f推時(shí),是兩條路一起走的,不存在哪條路先走,這樣就可以保證兩條路的一致性。
仔細(xì)觀察很容易得到一個(gè)這樣的結(jié)論 紙條傳的橫坐標(biāo)+縱坐標(biāo)=走的步數(shù); 通過這個(gè)結(jié)論便很簡(jiǎn)單的消維。
參考博客: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; }
總結(jié)
以上是生活随笔為你收集整理的nyoj 61(双线程dp)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【JEECG技术博文】jeecg 定时任
- 下一篇: 微信公众帐号开发教程第15篇-自定义菜单