牧场物语 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;
}
小茗同学突然心血来潮要去砍树,然而,斧头在小茗的右下方。
小茗是个讲究效率的人,所以他会以最短路程走到右下角,然后再返回到左上角。并且在路上都会捡到/踩到一些物品,比如说花朵,钱和大便等。
物品只能被取最多一次。位于某个格子时,如果格子上还有物品,就一定要取走。起点和终点上也可能有物品。
每种物品我们将为其定义一个价值,当然往返之后我们取得的物品的价值和越大越好。但是小茗同学正在认真地玩游戏,请你计算出最大的价值和。
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;
}
相关文章推荐
- 牧场物语 FZU - 2234 (双线DP)
- 牧场物语 FZU - 2234 (双线DP)
- 牧场物语 FZU - 2234 (双线DP)
- 牧场物语 FZU - 2234 (双线DP)
- 牧场物语 FZU - 2234 (双线DP)
- 牧场物语 FZU - 2234 (双线DP)
- 牧场物语 FZU - 2234 (双线DP)
- Fzu 2234 牧场物语(DP)
- FZU 2234 牧场物语【Dp】好题!好题!
- FZU2234 牧场物语 DP
- FZU 2234 牧场物语(多进程dp)
- FZU 2234 牧场物语(dp 好题)
- 2017年暑假组队训练赛-No.2 F - 牧场物语 FZU - 2234
- 牧场物语 FZU - 2234 巧妙的状态设计
- 双线dp ——牧场物语
- fzu - 牧场物语-2234 - 动态规划
- FZU2177——ytaaa——————【区间dp】
- FZU 2013 A short problem(DP)
- NYOJ 61 传纸条 && NYOJ 712 探寻宝藏 -- 双线dp
- FZU 2169 shadow (用了一次邻接表存边,树形DP)