花店橱窗

题意

给 f 朵花,v 个花瓶,每朵花对于每个花瓶都有一个美观值,现在期望美观值最大,让你输出最大的美观值,对于最大的美观值,输出每朵花在花瓶的位置,保证字典序最小。
有一个需要注意的条件是对于每朵花在花瓶的位置,一定大于上一个朵花的位置,也一定小于下一朵花的位置。

题解



首先需要初始化一下结果 dp 数组,让所有的结果都为负数,可能存在一种情况是,有一种花实在是不好看,在每个花瓶中美观值都为负数。

memset(dp, INF, sizeof(dp));

状态转换方程式:

for (int i = 0; i < v; ++ i) {
    dp[0][i] = a[0][i];
}
for (int i = 1; i < f; ++ i) {
    for (int j = 0; j < v; ++ j) {
        for (int k = 0; k < j; ++ k) {
            dp[i][j] = max(dp[i-1][k]+a[i][j], dp[i][j]);
        }
    }
}

回溯一下

    for (int i = 0; i < v; ++ i) {
        if (maxx == dp[f-1][i]) {
            pos = i;
            maxx -= a[f-1][i];
            break;
        }
    }
    res.push_back(pos);
    for (int i = f-2; i >= 0; -- i) {
        for (int j = 0; j < v; ++ j) {
            if (dp[i][j] == maxx) {
                maxx -= a[i][j];
                res.push_back(j);
                break;
            }
        }
    }
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll INF = -0X3f3f3f;
const int maxn = 105;
vector<int> res;
ll dp[maxn][maxn];
int a[maxn][maxn];
int main() {
    memset(dp, INF, sizeof(dp));
    int f, v;
    cin >> f >> v;
    for (int i = 0; i < f; ++ i) {
        for (int j = 0; j < v; ++ j) {
            cin >> a[i][j];
        }
    }
    for (int i = 0; i < v; ++ i) {
        dp[0][i] = a[0][i];
    }
    for (int i = 1; i < f; ++ i) {
        for (int j = 0; j < v; ++ j) {
            for (int k = 0; k < j; ++ k) {
                dp[i][j] = max(dp[i-1][k]+a[i][j], dp[i][j]);
            }
        }
    }
    ll maxx = 0, pos = 0;
    for (int i = 0; i < v; ++ i) {
        maxx = max(maxx, dp[f-1][i]);
    }

    cout << maxx << endl;
    for (int i = 0; i < v; ++ i) {
        if (maxx == dp[f-1][i]) {
            pos = i;
            maxx -= a[f-1][i];
            break;
        }
    }
    res.push_back(pos);
    for (int i = f-2; i >= 0; -- i) {
        for (int j = 0; j < v; ++ j) {
            if (dp[i][j] == maxx) {
                maxx -= a[i][j];
                res.push_back(j);
                break;
            }
        }
    }

    sort(res.begin(), res.end());
    for (auto x : res) {
        cout << x+1 << " ";
    }
    cout << endl;
    return 0;
}