题意
- 花店有f朵花,v个盆,每个花放每个盆有不同的美观度,求如何摆放能使美观度最大
- 特别的,给花编上号,花必须按照顺序摆放,编号小的的花不能放在编号大的花的后面
思路
- 由于必须按照顺序摆放,所以新的一盆花可放的盆一定是上一盆花放的盆的后面


- 初始化:对于最开始,每朵花放在自己编号的盆里
,其它位置都放极小值即可
- 对于输出路径,使用
记录到(i,j)这个点是谁转移来的,然后dfs回溯即可
代码
#include<bits/stdc++.h>
using namespace std;
/**
* 所有的花束在放入花瓶时必须保持其标识数的顺序,即:
* 杜鹃花必须放在秋海棠左边的花瓶中
* 秋海棠必须放在康乃馨左边的花瓶中
* dp[i][j]表示前i朵花,用前j个盆且第i朵花放到第j个盆里最大价值
* dp[i][j]=dp[i-1][1~j-1]+a[i][j]
* 初始化:没放的时候每个位置都应该是极小值,第0行应该是0,便于转移,每个花盆放在最小位置需要手动初始化
*/
long long dp[120][120];
long long val[120][120];
int path[120][120];
void printpath(int n,int dep){
if(dep==0) return;
printpath(path[dep][n],dep-1);
cout << n << ' ' ;
}
int 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];
}
}
for(int i=1;i<=f;i++){
for(int j=1;j<=v;j++){
dp[i][j]=-0x3f3f3f3f;
if(i==j){
dp[i][j]=dp[i-1][j-1]+val[i][j];
path[i][j]=i-1;
}
}
}
for(int i=1;i<=f;i++){
for(int j=1;j<=v;j++){
for(int k=1;k<j;k++){
if(dp[i][j]<dp[i-1][k]+val[i][j]){
dp[i][j]=dp[i-1][k]+val[i][j];
path[i][j]=k;
}
}
}
}
long long ans=-0x3f3f3f3f;
int idx=-1;
for(int i=f;i<=v;i++){
if(dp[f][i]>ans){
ans=dp[f][i];
idx=i;
}
}
cout << ans << endl ;
printpath(idx,f);
return 0;
}