sgu 104 Little Shop of Flowers

题意:第2朵花放的花瓶编号要比第1朵花放的编号大。给出各花放各花瓶的价值,要价值和最大。

dp[i][j]表示第I朵花必须放在第j瓶中的前i朵花最大收益和。那么就等于dp[i-1][j]中的最大+当前花的价值。复杂度n^3。

看了别人的,还能用dp[i][j]表示第i朵花放第j瓶以内的最大收益和。那么,dp[i][j]要么不放第j瓶,就等于dp[i][j-1]要么放第j瓶,等于dp[i-1][j-1]中的最大+第i朵花放第j瓶价值。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
using namespace std;
const double EPS=1e-8;
typedef long long lon;
const lon SZ=120,INF=0x7FFFFFFF;
lon arr[SZ][SZ],dp[SZ][SZ];

void work(lon n,lon m)
{
    for(lon i=1;i<=m;++i)dp[1][i]=arr[1][i];
    for(lon i=2;i<=n;++i)
    {
        for(lon j=1;j<=m;++j)
        {
            dp[i][j]=-INF;
            for(lon k=1;k<j;++k)
            {
                dp[i][j]=max(dp[i][j],dp[i-1][k]+arr[i][j]);
            }
        }
    }
    lon dst=*max_element(dp[n]+1,dp[n]+m+1);
    cout<<dst<<endl;
    vector<int> vct;
    for(int i=n;i>=1;--i)
    {
        for(int j=1;j<=m;++j)
        {
            if(dp[i][j]==dst)
            {
                vct.push_back(j);
                dst=dst-arr[i][j];
                break;
            }
        }
    }
    for(int i=vct.size()-1;i>=0;--i)
    {
        if(i!=vct.size()-1)cout<<" ";
        cout<<vct[i];
    }cout<<endl;
}

int main()
{
    std::ios::sync_with_stdio(0);
    //freopen("d:\\1.txt","r",stdin);
    lon n,m;
    cin>>n>>m;
    for(lon i=1;i<=n;++i)
    {
        for(lon j=1;j<=m;++j)cin>>arr[i][j];
    }
    work(n,m);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/gaudar/p/9752616.html
sgu
104