CF Round 245D.Working Out DP(不相交路径)

题意:n*m矩阵,(i,j)的价值为a[i][j],两个起点分别为(1,n),(n,1) 对应终点为(n,m).(1,m).
第一个起点的人只能向下和右移动,第二个起点的人只能向上和右移动.
1<=n,m<=1e3.问这两个人的路径正好只有一个交点时的最大价值?


枚举交点(x,y) 那么(1,1),(n,1) 到(x,y)的路径不能相交并且价值要尽量大.
设f[x][y]为(1,1)到(x,y)的最大价值,d[x][y]为(n,1)到(x,y)最大价值.
最后一次走法,只有四种分别是,右右,右上,下右,下上.
走法右右,会导致在(x,y-1)相遇, 走法下上 会使得下一步无论怎么走都重合.


(1,1)->(x,y-1) 和(n,1)->(x+1,y) 显然不会有交点.(因为第一个走的都在row[1:x],第二个在row:[x+1,n])

res[x][y]=max(f[x][y-1]+d[x+1][y]+ff[x][y+1]+dd[x-1][y],f[x-1][y]+d[x][y-1]+ff[x+1][y]+dd[x][y+1]).

#include <bits/stdc++.h>
using namespace std;
const int N=2e3+5;
int n,m,a[N][N],f[N][N],d[N][N],ff[N][N],dd[N][N];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>a[i][j],f[i][j]=a[i][j]+max(f[i-1][j],f[i][j-1]);
	for(int i=n;i>=1;i--)
		for(int j=1;j<=m;j++)
			d[i][j]=a[i][j]+max(d[i+1][j],d[i][j-1]);
	for(int i=n;i>=1;i--)
		for(int j=m;j>=1;j--)
			ff[i][j]=a[i][j]+max(ff[i+1][j],ff[i][j+1]);
	for(int i=1;i<=n;i++)
		for(int j=m;j>=1;j--)
			dd[i][j]=a[i][j]+max(dd[i][j+1],dd[i-1][j]);
	int res=0;
	for(int i=2;i<n;i++)
	{
		for(int j=2;j<m;j++)
		{
			int t1=f[i][j-1]+d[i+1][j]+ff[i][j+1]+dd[i-1][j];
			int t2=f[i-1][j]+d[i][j-1]+dd[i][j+1]+ff[i+1][j];
			int tot=max(t1,t2); 
			res=max(res,tot);
		}
	}
	cout<<res<<'\n';
	return 0;
 } 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值