动态规划题
用dp[i][j]表示把前i束花放在前j个花瓶里所得到的最大的美观值(i<=j)。
递推式为:dp[i][j] = max(dp[i][j-1], dp[i-1][j-1] + A[i][j]),dp[F][V]即为所求。
题目还要求输出每束花的摆放位置,可以用pre[i][j]=0或1表示dp[i][j]是由dp[i][j-1]或dp[i-1][j-1] + A[i][j]得来的,然后递归输出结果,具体看代码中的print(int, int)函数。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 110;
int f, v;
int a[maxn][maxn], dp[maxn][maxn];
int pre[maxn][maxn];
int DP()
{
dp[0][0] = 0;
for (int i = 1; i <= f; ++i)
{
dp[i][i-1] = -100000;
}
for (int i = 1; i <= f; ++i)
{
for (int j = i; j <= v; ++j)
{
if (dp[i][j-1] > dp[i-1][j-1] + a[i][j])
{
dp[i][j] = dp[i][j-1];
pre[i][j] = 0;
}
else
{
dp[i][j] = dp[i-1][j-1] + a[i][j];
pre[i][j] = 1;
}
}
}
return dp[f][v];
}
void print(int i, int j)
{
if (j == 0) return ;
if (pre[i][j] == 1)
{
print(i - 1, j - 1);
if (i == f)
printf("%d\n", j);
else
printf("%d ", j);
}
else print(i, j - 1);
}
int main()
{
while (scanf("%d %d", &f, &v) != EOF)
{
for (int i = 1; i <= f; ++i)
{
for (int j = 1; j <= v; ++j)
{
scanf("%d", &a[i][j]);
}
}
printf("%d\n", DP());
print(f, v);
}
return 0;
}