SGU104 Little shop of flowers

2 篇文章 0 订阅

好久没有做SGU了,今天来刷一道。


题目大意:
有V个花瓶 (1V100) ,有F束花 (1F100) ,且 FV ,现在要把所有的花放进V个花瓶中,且每个花瓶中只能放一束花,花必须按照编号由小到大的顺序放在花瓶中。也就是说 i<j ,都有花瓶i中的花的编号小于花瓶j中的花的编号。每一束花放在不同的花瓶中都有不同的美感,给出每一束花放在每一个花瓶中的美感,求一种安排使得所有花的美感和最大。

又是一道水题。。。
我的做法可能比较复杂,但还是很好理解的:
对于A数组,如下:
这里写图片描述

很容易发现有一部分是不可能用到的,如下:
这里写图片描述
所以可以转换成如下矩阵,求从(1,1)开始一条到达最后一行的路径,且每次只能往下一行横坐标不变小的位置移动,答案就是这条路径的最大权值。
这里写图片描述

然后DP一下就过了。

代码如下:

/*
ID: Sunshine_cfbsl
LANG: C++
*/
#include<cstdio>
#include<stack>
#include<algorithm>
#include<cstring>
using namespace std;

const int MAXF = 110, MAXV = 110;
const long long INF = 1LL<<62;

int f, v;
long long a[MAXF][MAXV], dp[MAXF][MAXV], ans = -INF;
stack<long long> s;

int main() {
    int i, j;
    scanf("%d%d", &f, &v);
    for(i = 1; i <= f; i++) 
        for(j = 1; j <= v; j++)
            scanf("%lld", &a[i][j]);
    for(i = 1; i <= f; i++)
        for(j = i; j <= v-f+i; j++) 
            a[i][j-i+1] = a[i][j];
    int n = v-f+1, loc;
    for(i = 1; i <= n; i++) dp[1][i] = a[1][i];
    for(i = 2; i <= f; i++) 
        for(j = 1; j <= n; j++) dp[i][j] = -INF;
    for(i = 2; i <= f; i++) {
        for(j = 1; j <= n; j++) {
            if(j > 1) dp[i][j] = max(dp[i][j], dp[i][j-1]-a[i][j-1]+a[i][j]);
            dp[i][j] = max(dp[i][j], dp[i-1][j]+a[i][j]);
        }
    }
    for(i = 1; i <= n; i++) {
        if(dp[f][i] > ans) {
            ans = dp[f][i];
            loc = i;
        }
    }
    printf("%lld\n", ans);
    s.push(loc+f-1);
    for(i = f; i >= 2; i--) {
        if(loc > 1 && dp[i][loc] == dp[i][loc-1]-a[i][loc-1]+a[i][loc]) {
            loc--;
            i++;
        }
        else if(dp[i][loc] == dp[i-1][loc]+a[i][loc]) s.push(loc+i-2);
    }
    while(s.size() > 1) {
        printf("%lld ", s.top());
        s.pop();
    }
    printf("%lld\n", s.top());
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值