这道题是DP题。应该能够自己发现的。结果还是先看了discuss,发现是比较简单的DP后做的。
定义DP[i][j]为把花i放在瓶j(包括j)之后的情况从i(包括i)之后的所有花能得到的最大值。
填充DP, 然后返回DP[0][0]就好。
做法是把花从后往前遍历,花瓶也从后往前遍历,且只考虑可能的花瓶(太后或太前会导致其他花没地方放)。
DP[i][j] = max(A[i][j] + DP[i + 1][j + 1], DP[i][j + 1]);两种情况:花i放在瓶j或者不放(那就必须放在j之后了),取最大值。
thestoryofsnow | 1157 | Accepted | 212K | 16MS | C++ | 1012B |
/*
ID: thestor1
LANG: C++
TASK: poj1157
*/
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <limits>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <cassert>
using namespace std;
// const int INF = 5000;
const int MAXN = 100;
int main()
{
int A[MAXN][MAXN], DP[MAXN][MAXN];
int F, V;
scanf("%d%d", &F, &V);
for (int i = 0; i < F; ++i)
{
for (int j = 0; j < V; ++j)
{
scanf("%d", &A[i][j]);
}
}
DP[F - 1][V - 1] = A[F - 1][V - 1];
for (int j = V - 2; j >= F - 1; --j)
{
DP[F - 1][j] = max(A[F - 1][j], DP[F - 1][j + 1]);
}
for (int i = F - 2; i >= 0; --i)
{
int j = V - F + i;
DP[i][j] = A[i][j] + DP[i + 1][j + 1];
j--;
while (j >= i)
{
DP[i][j] = max(A[i][j] + DP[i + 1][j + 1], DP[i][j + 1]);
j--;
}
}
printf("%d\n", DP[0][0]);
return 0;
}