花店橱窗布置

题目链接:https://www.luogu.com.cn/problem/P1854

题意:

给定f朵花,v个花瓶(v>=f)

每朵花在不同花瓶都有不同的权值

规定每朵花的相对次序不能改变

求将所有花都塞入花瓶时的最大权值和以及获得其的路径

思路:

记dp[i][j]:第i朵花塞入第j个瓶子时的最大权值和

显然需要从上一朵花转移得到

极限情况下第i朵花塞入瓶子编号最小值为i,最大为v

dp[i][j]=max(dp[i][j],dp[i-1][p]+g[i][j])

其中p的范围为[i-1,j-1],保证相对次序

另外dp数组初始化时考虑权值和有可能是负的,所以除了dp[0][i]都为-inf

对于求路径问题,需要开一个pre二维数组

对于每一个(i,j),转移权值最大时pre[i][j]就指向的是(i-1,temp)这个位置

int g[105][105];
int pre[105][105];
int dp[105][105];
int path[105];
void solve(){
    int f,v;cin>>f>>v;
    memset(dp,-inf,sizeof dp);
    rep(i,1,f){
        rep(j,1,v){
            cin>>g[i][j];
        }
    }

    rep(i,0,v){
        dp[0][i]=0;
        pre[0][i]=-1;
    }

   for(int i=1;i<=f;i++){
        for(int j=i;j<=v;j++){
            for(int p=i-1;p<j;p++){
                if(dp[i][j]<dp[i-1][p]+g[i][j]){
                    dp[i][j]=dp[i-1][p]+g[i][j];
                    pre[i][j]=p;
                }
            }
        }
   }
   
   int big=-inf;
   int temp=-1;
   for(int i=f;i<=v;i++){
        if(big<dp[f][i]){
            big=dp[f][i];
            temp=i;
        }
   }    
   cout<<big<<endl;
   int pos=f;
   vector<int>ans;
   while(pos!=0){
        ans.pb(temp);
        temp=pre[pos][temp];
        pos--;
   }
   for(int i=ans.size()-1;i>=0;i--){
        cout<<ans[i]<<' ';
   }
}
posted @ 2025-05-08 11:53  Marinaco  阅读(10)  评论(0)    收藏  举报
//雪花飘落效果