codevs1169传纸条
这题挺有意思的:传纸条
题目既然要我们找两条不相交的路(从左上到右下,从右下到左上)
并且要使其路上权值之和最大
我们可以等价于什么?
从左上到右下找两条路,同时走到右下,并且其路上权值和最大
假设有两个人在走,第一个人的坐标为(x1,y1),第二个人的坐标为(x2,y2)
因为只能向右或者是向下所以不难得出dp方程式
dp[x1,y1,x2,y2]=max(dp[x1-1,y1,x2-1,y2],dp[x1-1,y1,x2,y2-1],dp[x1,y1-1,x2-1,y2],dp[x1,y1-1,x2,y2-1])+G[x1][y1]+G[x2][y2];
可以看到这个方程式相当简单粗暴
for嵌套了四个,但还有一个细节是需要注意的,就是当他们走到了同一个点
这种情况是拒绝出现的
(为什么?答案:曼哈顿距离)
曼哈顿距离说明了只有两个人走到同一个点才可能发生路线交叉
所以我们只要特判一下
if(x1==x2 and y1==2)
continue;
就行了
时间复杂度O(n^4)
后来听说还有一种方法可以改进为n^3
我就百度了一下,下面引用一下别人家的思想,看看就差不多了
因为 两个人是同时走的所以 每次都是同时移动一格:因此有 x1+y1==x2+y2 == k
则状态方程可以改为:
f(k,x1,x2) = max{ f(k-1,x1,x2), f(k-1,x-1,x2) ,f(k-1,x1,x2-1), f(k-1,x1-1,x2-1) } + map[x1][k-x1] + map[x2][k-x2]
for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { for(int k=1;k<=n;k++) { for(int l=1;l<=m;l++) { if(i==k && j==l) continue; maxn=max(dp[i-1][j][k-1][l],dp[i-1][j][k][l-1]); maxn=max(maxn,dp[i][j-1][k-1][l]); maxn=max(maxn,dp[i][j-1][k][l-1]); dp[i][j][k][l]=maxn+G[i][j]+G[k][l]; } } } }
最后再说一句,这代码未经测试,错了别怪我 :)
---QQ:2602626065