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;
}