【洛谷P1006】傳紙條【DP】
阿新 • • 發佈:2018-11-22
題目大意:
題目連結:https://www.luogu.org/problemnew/show/P1006
給出一個
的矩陣,每個格子中有權值,求從
到
的兩條不相交路徑使得路徑權值之和最大。
思路:
很明顯可以把題目看成兩條不相交的路徑從
到
。那麼就可以設
表示第一條路走到
,第二條路走到
時的權值最大值。那麼由於可以直接從上和下兩個方向轉移過來,所以就有方程
那麼最終答案很明顯就是
。
但是這樣的時空複雜度太不理想了,所以可以考慮剪枝。
我們發現,如果走了
步,橫座標為
,那麼很明顯縱座標就是
。因為只能往下或右走。那麼我們就可以想到另一種方法:
設
表示走了
步,兩條路的橫座標分別是
和
時的最大權值和。
這樣我們就可以算出兩條路的縱座標,進而進行轉移。
方程如下:
那麼最終答案就是
。
這樣時間複雜度就變成了
。
題外話
這道題還可以用網路流做。
摘自 https://www.luogu.org/blog/user21682/solution-p1006
程式碼:
#include <cstdio>
#include <iostream>
using namespace std;
int a[51][51],f[51][51][51][51],m,x,y,n,k;
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
for (int q=1;q<=n;q++)
for (int p=1;p<=m;p++)
{
f[i][j][q][p]=max(f[i-1][j][q-1][p],max(f[i][j-1][q-1][p],max(f[i-1][j][q][p-1],f[i][j-1][q][p-1])))+a[i][j]+a[q][p];
if(i==q&&j==p)f[i][j][q][p]-=a[i][j];
}
printf("%d",f[n][m][n][m]);
return 0;
}
#include <cstdio>
#include <iostream>
#define N 60
using namespace std;
int n,m,f[N+N][N][N],a[N][N];
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++