【算法竞赛进阶指南】CH5103 NOIP2008 T3 传纸条 线性dp

解决一个N*M矩阵的问题,寻找两条从左上角到右下角不经过相同格子的最优路径,使路径上数字和最大化。动态规划策略是使用3个变量表示路径状态,并以初始和目标状态进行计算。
摘要由CSDN通过智能技术生成
Description

给定一个 N*M 的矩阵A,每个格子中有一个整数。现在需要找到两条从左上角 (1,1) 到右下角 (N,M) 的路径,路径上的每一步只能向右或向下走。路径经过的格子中的数会被取走。两条路径不能经过同一个格子。求取得的数之和最大是多少。N,M≤50。

数据规模约定:
30%的数据满足:1<=m,n<=10
100%的数据满足:1<=m,n<=50

Input

第一行有2个用空格隔开的整数n和m,表示有n行m列(1<=n,m<=50)。
接下来的n行是一个n*m的矩阵,每行的n个整数之间用空格隔开。

Output

一个整数,表示答案。

Sample Input
3 3
0 3 9
2 8 5
5 7 0
Sample Output
34

状态:路径长度/当前走过的步数。
记当前的步数为i,当前的两个坐标分别为x1,y1、x2,y2。我们可以只用3个变量i,x1,x2,F[i,x1,x2] 代表当前状态(y1 = i + 2 - x1,y2 = i + 2 - x2)。
起始状态:F[0,1,1] = A[1,1]
目标状态:F[N+M-2,N,N] = A[N,N]


#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 56;
int n, m, g[maxn][maxn], f[maxn << 1][maxn][maxn];

void dp()
{
   
	for (int i = 0; i < n + m - 2; i++)
		// j是第一条路径上点的横坐标x1
		for (int j = 1; j <= n && j <= i + 1; j++)
			// k是第二条路径上点的横坐标x2
			for (int k = 1; k <= n && k <= i + 1; k++)
			{
   
				// 1. 下次都向一个方向扩展

				// 当前两个在一个格子 -> 两条路径可以扩展到同一个格子
				if (j == k
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值