洛谷OJ: P1006 传纸条

博主通过画图发现每条从右上到左下的斜线涉及两位同学,借鉴n皇后问题中斜线的规律,构建状态转移方程。定义dp[k][i][j]表示横纵坐标为k的斜线上,下线横坐标i,上线横坐标j(i<j)。经过一个小时思考,找出四种转移形式:下下、右右、下右、右下,并据此得出转移方程: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]。动态规划难题。" 79851741,7414467,使用C#的Repeater控件创建不规则表格,"['VS', 'C#', '前端', 'table', 'repeater']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:开始看到这题的时候无从下手,于是就在纸上试着画出路线,看看有没有什么规律,画着画着发现在画完路线的图上每一条从右上到左下的斜线都只用到了两个同学,并且在斜线上一条线路永远在另一条线路的右上方,因为做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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值