[NOIP2008]传纸条(含空间压缩优化)

分析

这道题和NOIP2000的方格取数如出一辙(超详细题解在此),都是给定矩阵,要求从左上角走到最下角(只可向右或向左走)找两条路径,使两条路径上数字的总和最大。但这题有几个变化:

  1. 路径不可相交。
  2. 矩阵形态不一样:原题是方阵,这题是任意矩阵。(但这个变化没有什么影响)
  3. 数据范围有所扩大:原题是9以内,这题是50。(但如果用动规做,O(n3)的时间复杂度依旧不会超时)

解法依然是动规,两条路线同时走,状态是[y1][x1][y2][x2]表示两条路线分别走到(x1,y1)和(x2,y2)……阶段、状态转移方程也都一样,省略100~200字…….只是为了确保路径不可相交,不妨设路线1始终在路线2的左侧,可以加上x1<x2这个限制条件来保证

代码大体一样,复杂度也一样,时间复杂度O(n3),空间复杂度O(n4)。

代码

注意

  1. 状态转移时,要判断上一状态是否在边界内、是否合法。
  2. 如果对最后一轮也加了x1<x2限制,最后状态不再是求[m][n][m][n],而是[m][n-1][m-1][n](倒数第二轮的状态),路线1的终点和路线2的终点只有这一种可能,一条到达终点左边一格,另一条到达终点上边一格。
  3. 当m或n为1时,无法找到两个不相交路径,需输出0。
#include <stdio.h>
#include <string.h>

int max(int a,int b) {
   return a>b?a:b;}

/* dp[y1][x1][y2][x2] (x1<x2) = max{
   a[y1][x1] + a[y2][x2] + max{dp[y1-1][x1][y2-1][x2], dp[y1][x1-1][y2][x2-1], dp[y1-1][x1][y2][x2-1], dp[y1][x1-1][y2-1][x2]}
	}
*/

const int dir[2][2]={
   {
   1,0},{
   0,1}};

int main()
{
   
	// load data
	int m,n;
	while (2==scanf("%d%d",&m,&n))
	{
   
		static int a[51][51];
		static int dp[51][51][51][51];
		int x,y,num;
		memset(a,0,sizeof(a));
		memset(dp,-1,sizeof(dp));
		for (int y=1;y<=m;y++)
			for (int x=1;x<=n;x++)
				scanf("%d",&a[y][x]);
		// solve (dynamic planning)
		dp
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值