Problem 2234 牧场物语
Problem Description
小茗同学正在玩牧场物语。该游戏的地图可看成一个边长为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一遍,先求个最大值,再标记走过的点为0,倒着回去再dp一遍,再求个最大值,两个最大值一加就好了。但一直WA。不知道这算不算记忆化,不知道(怎么写)哪里写错了。(目前发现了边界写的不对)也请过路大牛指教:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = ;
typedef long long ll;
ll dp1[MAXN][MAXN], dp2[MAXN][MAXN];
ll a[MAXN][MAXN], path[MAXN][MAXN]; void update(int x, int y)
{
if (x <= || y <= ) return;
a[x][y] = ;
if (path[x][y] == ) {
update(x - , y);
}
else if (path[x][y] == ) {
update(x, y - );
}
else return;
} int main()
{
int N;
while (cin >> N)
{
for (int i = ; i <= N; i++)
for (int j = ; j <= N; j++)
cin >> a[i][j];
memset(path, -, sizeof(path));
memset(dp1, , sizeof(dp1));
memset(dp2, , sizeof(dp2));
for (int i = ; i <= N; i++)
for (int j = ; j <= N; j++)
{
if (dp1[i - ][j] > dp1[i][j - ]) {
dp1[i][j] = a[i][j] + dp1[i - ][j];
path[i][j] = ;
}
else
{
dp1[i][j] = a[i][j] + dp1[i][j - ];
path[i][j] = ;
}
}
a[N][N] = ;
a[][] = ;
update(N, N);
for (int i = N; i >= ; i--)
for (int j = N; j >= ; j--)
dp2[i][j] = a[i][j] + max(dp2[i + ][j], dp2[i][j + ]);
cout << dp1[N][N] + dp2[][] << endl;
}
return ;
}
WA了
或者,我想难道是这个方法有漏洞?
后来,我看了好多网上的博客,感觉大牛们的想法出奇的一致!:可以把问题转化成两个人同时走。两个人同时走?我一个人来回走就不行???
05-11 04:44