洛谷OJ: P1006 传纸条

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Elvis_code_t/article/details/79946287

思路:开始看到这题的时候无从下手,于是就在纸上试着画出路线,看看有没有什么规律,画着画着发现在画完路线的图上每一条从右上到左下的斜线都只用到了两个同学,并且在斜线上一条线路永远在另一条线路的右上方,因为做n皇后问题的时候有利用过这种斜线,于是就想以这个作为突破口写出状态转移方程,思考了有一个小时吧...最后才得到了状态转移方程

首先我们定义dp[k][i][j]的意义为横纵坐标为k的斜线上, 在下面的线路横坐标为i, 在上面的线路的横坐标为j, 所以i < j恒成立, 那么应该如何递推呢?通过画图枚举我得到了四种方式


即 1.下下2.右右3.下右4.右下 这四种转移形式

那么我们便可以得到转移方程

dp[k][i][j] = max{dp[k-1][i][j], dp[k-1][i-1][j-1], dp[k-1][i][j-1], dp[k-1][i-1][j]} + maps[i][j]

DP还是难啊!!!!!!

/**
 *	题目: 洛谷OJ P1006 传纸条
 *	题型: DP
 **/
#include <cstdio>
#include <iostream>
using namespace std;

const int maxn = 100+10;
int dp[maxn<<1][maxn][maxn], maps[maxn][maxn], n, m, ans;

int main()  {
	ios::sync_with_stdio(false);
	/************input**************/
	cin >> n >> m;
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= m; j++) {
			cin >> maps[i][j];
		}
	}
	/*******************************/
	for(int k = 2; k <= n+m-1; k++) {
		for(int i = 1; i <= k-1; i++) {
			for(int j = i+1; j <= k-1; j++) { //因为在同一条斜线上横坐标不可能相同, 所以j从i+1开始 
				dp[k][i][j] = max(dp[k-1][i][j], max(dp[k-1][i-1][j-1],dp[k-1][i-1][j])) + maps[i][k-i] + maps[j][k-j];
			}
		}
	}
	cout << dp[n+m-1][n-1][n] << endl;
	return 0;
}

阅读更多 登录后自动展开
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页