一、考虑状态转移方程怎么写:

1、首先考虑子问题是怎么样的,原问题是求把编号为1~ f的花束,随机放进1~v这v个瓶子里面,且需要按照编号顺序放置,每个花瓶只能放一朵花,的最美观方案。

子问题就可以是,把编号为1~ i的花束,随机放进1~j这j个瓶子里面的最美观方案。显然子问题和原问题的求解方法是一样的,子问题假设正确。

2、接着分析后效性,首先构造一个一维dp数组,dp[M],描述第M朵花放置在第i个花瓶时的最美观方案,当前状态的选择一定会影响后一个状态的决策,这个状态选了一个数值,为了保证得到最美观方案,下一个状态还需要讨论选哪个数值更好,很复杂,不符合动态规划的本意。

消除后效性

增加一个维度,变为dp[M][M],表示前i多花按顺序任意放置在前j个花瓶中的最美观方案。

#include<bits/stdc++.h>
using namespace std;
int f,v;
const int M=105;
int a[M][M];    //第几种花 第几个花瓶
int dp[M][M];
void printmax(int maxn,int i,int j){
    if(i==0) return ;
    for(int k=1;k<=v;k++){
        if(dp[i-1][k]+a[i][j]==maxn){
            printmax(dp[i-1][k],i-1,k);
            break;
        }
    }
    cout<<j<<" ";
}
int main(){
    cin>>f>>v;
    for(int i=1;i<=f;i++){
        for(int j=1;j<=v;j++){
            cin>>a[i][j];
            dp[i][j]=-10000;
        }
    }
    for(int i=1;i<=v;i++) dp[1][i]=a[1][i];
    for(int i=1;i<=f;i++){
        for(int j=i;j<=v-(f-i);j++){
            for(int k=i-1;k<j;k++){
                dp[i][j]=max(dp[i][j],dp[i-1][k]+a[i][j]);
            }
        }
    }
    int pos=0;
	int ans=-1e8;
	for(int i=f;i<=v;i++){
		if(ans<dp[f][i]){
            ans=dp[f][i];
            pos=i;
        }
	}
	cout<<ans<<endl;
    printmax(ans,f,pos);
	return 0;
}