AcWing 313. 花店橱窗(简单dp,输出方案)

传送门
题目描述起来有点麻烦,就不描述了.
关注题目给的特性,每朵花是按顺序插放的,这很符合dp中的阶段的特性.可以用dp[i][j]表示第i朵花插在第j个花瓶中的max.那转移方程就是:
dp[i][j] = max{dp[i-1][k],i-1<=k<=j-1}
这个方程因为j是固定的,内层还能够优化一下去掉一层循环,不过因为数据量比较小,直接暴力的做也可以.
输出方案可以用回溯的思想一个一个往上找(这也是dp问题找方案很常见的操作).
代码

#pragma GCC optimize(2)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>

using namespace std;
const int N = 1e2+10;

inline void read(int &a){
    
    
    int x = 0,f=1;char ch = getchar();
    while(ch<'0'||ch>'9'){
    
    if(ch=='-')f=-1;ch=getchar();}
    while(ch<='9'&&ch>='0'){
    
    x=x*10+ch-'0';ch=getchar();}
    a = x*f;
}
int n,m,a[N][N],dp[N][N];
int main(){
    
    
    cin >> n >> m;
    fir(i,1,n) fir(j,1,m) cin >> a[i][j];
    mem(dp,0x8f);
    dp[0][0] = 0;
    fir(i,1,n){
    
    
        fir(j,1,min(m,m-(n-i))){
    
    
            fir(k,i-1,j-1){
    
    
                dp[i][j] = max(dp[i][j],dp[i-1][k]+a[i][j]);
            }
        }
    }
    int ans = INT_MIN;
    fir(i,n,m) ans = max(ans,dp[n][i]);
    cout << ans << endl;
    int i = n;
    vi vec;
    while(i){
    
    
        fir(j,1,m){
    
    
            if(dp[i][j] == ans){
    
    
                vec.pb(j);
                ans -= a[i][j];
                i--;
                break;
            }
        }
    }
    reverse(ALL(vec));
    for(auto x:vec) cout << x << " ";
    
    return 0;
}    


/*
    dp[i][j] 第i个花放在第j个花瓶
*/

猜你喜欢

转载自blog.csdn.net/weixin_45590210/article/details/107841275
今日推荐