P1854 花店橱窗布置
思路
状态转移较易确认,需要注意的是记录路径的方法:定义二维数组 pre:dp[i][j]时,它的上一朵花的位置。那么在查询路径时就要层层向上搜寻(类似并查集的结构),找到每一朵花算在的瓶的位置。由于题目中美学值可能为负数,因此初始化需要置为一个负数,特殊项置 0 。
代码
#include<iostream>
#include<cstring>
using namespace std;
int F, V, dp[107][107], pre[107][107], val[107][107], ans, foot[107];
int main(void)
{
cin >> F >> V;
for (int i = 1; i <= F; i++)
for (int j = 1; j <= V; j++)
cin >> val[i][j];
for (int i = 1; i <= F; i++)
for (int j = 1; j <= V; j++)
dp[i][j] = -32767;
for (int i = 1; i <= F; i++)
dp[0][i] = 0;
for (int i = 1; i <= F; i++)
{
for (int j = i; j <= V - F + i; j++)
{
for (int k = i - 1; k <= j - 1; k++)
{
if (dp[i - 1][k] + val[i][j] > dp[i][j]) {
dp[i][j] = dp[i - 1][k] + val[i][j];
pre[i][j] = k;
}
}
}
}
for(int i=F;i<=V;i++)
if (dp[F][i] > ans) {
ans = dp[F][i];
foot[F] = i;
}
for (int i = F; pre[i][foot[i]]; i--)
foot[i - 1] = pre[i][foot[i]];
cout << ans << endl;
for (int i = 1; i <= F; i++)
cout << foot[i] << " ";
return 0;
}