洛谷刷题C++语言 | P1854 花店橱窗布置

学习C++从娃娃抓起!记录下洛谷C++学习和备考过程中的题目,记录每一个瞬间。

附上汇总贴:洛谷刷题C++语言 | 汇总


【题目描述】

某花店现有 F 束花,每一束花的品种都不一样。至少有同样数量的花瓶,被按顺序摆成一行。花瓶的位置是固定的,从左到右按 1∼V 顺序编号,V 是花瓶的数目。

花束可以移动,并且每束花用 1∼F 的整数标识。所有花束在放入花瓶时必须保持其标识数的顺序。例如,假设杜鹃花的标识数为 1,秋海棠的标识数为 2,康乃馨的标识数为 3,即杜鹃花必须放在秋海棠左边的花瓶中,秋海棠必须放在康乃馨左边的花瓶中。每个花瓶只能放一束花。

每个花瓶的形状和颜色也不相同,因此,当各个花瓶中放入不同的花束时,会产生不同的美学效果,并以美学值(一个整数 a i , j a_{i,j} ai,j)来表示,空置花瓶的美学值为 0。在上述的例子中,花瓶与花束的不同搭配所具有的美学值,可以用如下的表格来表示:

花瓶 1花瓶 2花瓶 3花瓶 4花瓶 5
杜鹃花723−5−2416
秋海棠521−41023
康乃馨−215−4−2020

根据表格,杜鹃花放在花瓶 2 中,会显得非常好看,但若放在花瓶 4 中,则显得很难看。

为了取得最佳的美学效果,必须在保持花束顺序的前提下,使花的摆放取得最大的美学值,如果具有最大美学值的摆放方式不止一种,则输出任何一种方案即可。

【输入】

输入文件的第一行是两个整数 F 和 V,分别为花束数和花瓶数。

接下来是矩阵 a i , j a_{i,j} ai,j,共 F 行,每行 V 个整数, a i , j a_{i,j} ai,j 表示花束 i 摆放在花瓶 j 中的美学值。

【输出】

输出文件的第一行是一个整数,为最大的美学值;接下来一行 F 个整数,为那束花放入那个花瓶的编号。

【输入样例】

3 5
7 23 -5 -24 16
5 21 -4 10 23
-21 5 -4 -20 20

【输出样例】

53
2 4 5

【代码详解】

在这里插入图片描述

// 使用动态规划方法
#include <bits/stdc++.h>
using namespace std;
int n, m, maxn, maxpos;
int a[105][105][2];
void dfs(int n, int pos)
{
    if (n==1) return;
    int x = a[n][pos][1];
    dfs(n-1, x);
    cout << x << " ";
}
int main()
{
    cin >> n >> m;
    for (int i=1; i<=n; i++)
        for (int j=1; j<=m; j++)
            cin >> a[i][j][0];
    for (int i=2; i<=n; i++) {
        maxn = -1e9;
        for (int j=i-1; j<=m-n+i-1; j++) {
            if (a[i-1][j][0]>maxn) {
                maxn = a[i-1][j][0];
                maxpos = j;
            }
            a[i][j+1][0] += maxn;
            a[i][j+1][1] = maxpos;
        } 
    }
    maxn = -1e9;
    if (m>3) {  // 第11个样例数据m=3,所以只可能是a[n][3][0]是最大值
        for (int i=m-n+1; i<=m; i++)
            if (a[n][i][0]>maxn) {
                maxn = a[n][i][0];
                maxpos = i;
            }
    } else {
        maxn = a[n][3][0];
        maxpos = 3;
    }
    cout << maxn << endl;
    // cout << "maxpos " << maxpos << endl;
    dfs(n, maxpos);
    cout << maxpos << endl;
    return 0;
}

【运行结果】

3 5
7 23 -5 -24 16
5 21 -4 10 23
-21 5 -4 -20 20
53
2 4 5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值