您的位置:首页 > 其它

牧场物语 FZU - 2234 (双线DP)

2017-12-25 16:19 211 查看
小茗同学正在玩牧场物语。该游戏的地图可看成一个边长为n的正方形。

小茗同学突然心血来潮要去砍树,然而,斧头在小茗的右下方。

小茗是个讲究效率的人,所以他会以最短路程走到右下角,然后再返回到左上角。并且在路上都会捡到/踩到一些物品,比如说花朵,钱和大便等。

物品只能被取最多一次。位于某个格子时,如果格子上还有物品,就一定要取走。起点和终点上也可能有物品。

每种物品我们将为其定义一个价值,当然往返之后我们取得的物品的价值和越大越好。但是小茗同学正在认真地玩游戏,请你计算出最大的价值和。

Input

多组数据(<=10),处理到EOF。

第一行输入正整数N(N≤100),表示正方形的大小。

接下来共N行,每行N个整数Ai,j(|Ai,j|≤10^9),表示相应对应位置上物品的价值。值为0表示没有物品。

Output

每组数据输出一个整数,表示最大价值和。

Sample Input

2

11 14

16 12

Sample Output

53

思路:双线DP

以考虑为有两个人一起出发,从起点到终点,路上取得最大权值。

f[k,(x1,y1),(x2,y2)]=max{

                    f[k-1,(x1,y1-1),(x2,y2-1)]+a[x1,y1]+a[x2,y2]

                    f[k-1,(x1,y1-1),(x2-1,y2)]+a[x1,y1]+a[x2,y2]

                    f[k-1,(x1-1,y1),(x2,y2-1)]+a[x1,y1]+a[x2,y2]

                    f[k-1,(x1-1,y1),(x2-1,y2)]+a[x1,y1]+a[x2,y2]  }

容易得到上述方程,k代表第几步,其他的都是字面意思。

然后x和y和k之间有关系,k+1=x+y,显然可以减掉两维了。状态化简为f[k][x1][x2]。因为k状态只由k-1的状态转移而来。所以再用滚动数组优化,(不然会爆空间)。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define ll long long
using namespace std;
ll v[110][110],f[210][110][110];
int main()
{
int t,n,m,c;
int i,j,k;
while(scanf("%d",&n)!=EOF)
{
c=n+n-1;
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
scanf("%I64d",&v[i][j]);
memset(f,-0x3f3f3f3f,sizeof(f));
f[1][1][1]=v[1][1];
for(k=2; k<=c; k++)
{
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
{
f[k][i][j]=max(max(f[k-1][i-1][j],f[k-1][i][j-1]),max(f[k-1][i][j],f[k-1][i-1][j-1]));
if(i!=j) //判断是否重复经过
f[k][i][j]+=v[i][k-i+1]+v[j][k-j+1];
else
f[k][i][j]+=v[i][k-i+1];
}

}
printf("%I64d\n",f[c]

);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp