1004 方格取数

1004 方格取数

这个题和去年那一道的方格取数不一样,他需要走两次,找到两个路径
我早就做过,不过只有20分,做的时候是去年,那时候我太垃圾了,现在我重新杀来
然后呢,因为是两个路径,那么状态必定就是四维
f[i][[j][l][k]表示第一个人走到(i,j),第二个人走到(l,k)的最大值
那么方程是啥,其实类似于数字三角形
在这里插入图片描述
就是方程了
然后需要特殊判断i=k j=l的情况,也就是两个点是相同的,多算了一次
一年了,终于切了

----------重新----------
题意很好理解了
就是一个人走两次,跑两个动态规划,当然不是单纯的跑“两次”
走两遍,这个题需要走两次
为什么走两次?走两次会怎么样,会使得这个题变成什么样?
循环输入,不能确定数量,所以直接先输入一个,然后接着循环搞
f[i][[j][l][k]表示第一个人走到(i,j),第二个人走到(l,k),这两次的最大值
意思就是走两次,开四位,这个数据小的可怜,n为9,94,也就是六千多,不用担心扎空间
动态规划的精髓就是如此,求什么设什么,类似于求函数,求方程
i j f[i][j]这三个,是基本的使用,标志着你需要的未知数
然后就是只能下走或者右走
但是我们计算是反过来求,也就是一个点通过向下或者向右走向这个i j
求上一个点,所以需要翻过来,ij有两种,kl也有两种,所以就是有四种的选择,最大获得值加上当前ij kl的数值
然后递推下去
如果两条路的一个点重合,我们会多取一个,把他减去就好了

#include<iostream> 
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
int n,x,y,z;
int f[15][15][15][15];
int a[20][20];
int main()
{
	cin>>n>>x>>y>>z;
	while(x||y||z)
	{
		a[x][y]=z;
		cin>>x>>y>>z;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			for(int k=1;k<=n;k++)
			{
				for(int l=1;l<=n;l++)
				{
					f[i][j][k][l]=max(max(f[i-1][j][k-1][l],f[i-1][j][k][l-1]),max(f[i][j-1][k-1][l],f[i][j-1][k][l-1]))+a[i][j]+a[k][l];
					if(i==k&&l==j) f[i][j][k][l]-=a[i][j];//特殊判断减去
				}
			}
		}
	}
	cout<<f[n][n][n][n]<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值