!-- Loading 底层遮罩 -->

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;
}

 

posted @ 2022-03-30 20:04  Thinker-X  阅读(130)  评论(0编辑  收藏  举报