是一个动态规划问题,不是背包问题,背包问题的特点在于有最优的值,而且有某种限制。在这里面需要将花插入花瓶当中,由于有所有的花束在放入花瓶时必须保持其标识数的顺序这个限制。所以应该最外层是以花作为遍历,这样可以保证这个顺序。
那么动态转移方程为:dp[i][j]=max(dp[i-1][1~j-1])+val[i][j];。
关于方案如何给出,在这里采用向前一个去寻找的方式,也就是记录当前i,j下是由上一个哪个转移过来的。这样只要找到最优的那一个向上去寻找,将路径保存进栈里面最后将栈输出即可。
#include <bits/stdc++.h>


using namespace std;

int node[100+10][100+10];
int dp[100+10][100+10];
int val[100+10][100+10];

signed main() {
    int f, v;
    cin>>f>>v;
    for (int i=1;i<=f;i++) {
        for (int j=1;j<=v;j++) {
            cin>>val[i][j];
            dp[i][j] = INT_MIN;
        }
    }
    for (int i=1;i<=f;i++) {
        for (int j=i;j<=v;j++) {
            dp[i][j] = val[i][j];
            int max_val;
            if (j==1)
                max_val = 0;
            else 
                max_val = INT_MIN;
            int max_pos;
            for (int k=1;k<j;k++) {
                if (dp[i-1][k]>max_val) {
                    max_val = dp[i-1][k];
                    max_pos = k;
                }
            }
            dp[i][j] += max_val;
            node[i][j] = max_pos;
        }
    }
    int ans = INT_MIN;
    int tar;
    for (int j=1;j<=v;j++) {
        if (dp[f][j]>ans) {
            ans = dp[f][j];
            tar = j;
        }
    }
    cout<<ans<<endl;
    stack<int> st;
    st.push(tar);
    for (int i=f;i>1;i--) {
        st.push(node[i][tar]);
        tar = node[i][tar];
    }
    for (int i=1;i<=f;i++) {
        cout<<st.top()<<" ";
        st.pop();
    }
    return 0;
}