传纸条

传纸条
题解:
显然这道题给了我们矩阵和坐标,那么我们就要根据矩阵和坐标进行dp,第一感觉肯定是用dp[x1][y1][x2][y2]表示当走到(x1,y1)和(x2,y2)时最大的值,但显然这是个n4的算法,非常危险,所以我们要优化。根据题意可以知道,x+y应该就等于step+1,那么我们当已知x时,就可以得出y,那么现在我们就可以用dp[i][x1][x2]来表示当走i步,走到了(x1,y1)和(x2,y2)时的最大值,但问题又来了,就是显然每个人我们只能传一次,那么我们就进行特殊判断,当x1=x2时,优先从x1传过来
代码:

#include
using namespace std;
int n,m,a[55][55],dp[105][55][55];
int max_4(int p,int q,int m,int n){
     
	return max(p,max(q,max(m,n)));
}
int main(){
     
	scanf("%d%d",&m,&n);
	for(int i=1;i<=m;i++)
		for(int j=1;j<=n;j++) scanf("%d",&a[i][j]);
	dp[1][1][1]=a[1][1];
	for(int i=2;i<=n+m-1;i++){
     
		for(int x1=1;x1<=n;x1++){
     
			if(i+1-x1>=1&&i+1-x1<=m){
     
				for(int x2=1;x2<=n;x2++){
     
					if(i+1-x2>=1&&i+1-x2<=m){
     
						dp[i][x1][x2]=max_4(dp[i-1][x1-1][x2],dp[i-1][x1][x2],dp[i-1][x1][x2-1],dp[i-1][x1-1][x2-1]);
						if(x1==x2) dp[i][x1][x2]+=a[x1][i+1-x1];
						else dp[i][x1][x2]+=a[x1][i+1-x1]+a[x2][i+1-x2];
					}
				}
			}
		}
	}
	printf("%d",dp[n+m-1][n][n]);
	return 0;
}

你可能感兴趣的:(c++,动态规划)