线性DP——花店橱窗

谨以此题解献给线性dp最后一道题

题目大致

Description

xq和他的老婆xz最近开了一家花店,他们准备把店里最好看的花都摆在橱窗里。但是他们有很多花瓶,每个花瓶都具有各自的特点,因此,当各个花瓶中放入不同的花束时,会产生不同的美学效果。为了使橱窗里的花摆放的最合适,他们得想个办法安排每种花的摆放位置。

可是因为xq和xz每天都太忙,没有时间设计橱窗里花的摆法,所以他们想让你帮他们求出花摆放的最大美观程度和每种花所放的位置。

注:标号小花必须放在标号大的前面。

每种花放在不同的瓶子里会产生不同的美观程度,美观程度可能是正数也可能是负数。

上述例子中,花瓶与花束的不同搭配所具有的美观程度,如下表所示:

花 瓶

1 2 3 4 5

1 (杜鹃花) 7 23 -5 -24 16

2 (秋海棠) 5 21 -4 10 23

3 (康乃馨) -21 5 -4 -20 20

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

Input Format

第1行:两个整数F和V,表示xq和xz一共有F种花,V个花瓶。(1<=F<=V<=100)

第2行到第F+1行:每行有V个数,表示花摆放在不同花瓶里的美观程度值value。(美观程度和不超过maxint,美观程度有正有负。)

Output Format

输出有两行:第一行为输出最大美观程度和的值,第二行有F个数表示每朵花应该摆放的花瓶的编号。

Sample

样例输入
3 5
7 23 -5 -24 16
5 21 -4 10 23
-21 5 -4 -20 20
样例输出
53
2 4 5

Hint

其实就是简单的DP,花店橱窗问题啦。

注意尽量靠前放啊!

解析

在题目中有几个比较重要的地方:

  1. 所有花都要按照规定的顺序排放
  2. 如有美观程度相等的方案,花遵循靠前放置的原则
  3. 本题涉及负数

我们再来看如何求解

先看样例:因为要顺序排放,所以我们先看1号花。1号花可以摆在1、2、3号花瓶,但不能摆在3,4号花瓶,否则剩下的两朵花就没有地方了。同样,2号花可以摆在2、3、4号花瓶,但不能摆在1、5上,否则1、3号花就没有位置了。

1 2 3 4 5
1 true true true false false
2 false true true true false
3 false false true true true

于是我们可以得出规律:我们只需要更新第\(i\)到第\(V-F+i\) (\(i\)为花的编号)的dp就可以了。也就是只更新绿色位置的dp状态。

然后,根据题目可知,花要顺序摆放,那么第\(i\)朵花也一定和第\(i-1\)的花有关。看样例:

下面的表格表示dp状态。我们令dp[花的编号][花瓶编号]。第一朵花没有前面的花,所以直接根据美观程度更新。第4、5号位不更新。

1 2 3 4 5
1 7 23 -5 0 0
2

接着更新dp[2],2、5号位不更新。第2号位置只能由dp[1][1]来更新,所以直接继承。dp[2][2] = dp[1][1] + w[2][2]。w表示不同花在不同花瓶的美观程度。

1 2 3 4 5
1 7 23 -5 0 0
2 7+21=28

更新dp[2][3]时,为了达到最大,需要找到dp[1][1]dp[1][2]的最大值,也就是dp[1][2]

1 2 3 4 5
1 7 23 -5 0 0
2 28 23+(-4)=19

同理可得:

1 2 3 4 5
1 7 23 -5 0 0
2 28 19 23+10=33
1 2 3 4 5
1 7 23 -5 0 0
2 7(无用) 28 19 33 0
3 7(无用) 28(无用) 24 8 53

易得,最大美观值为53。所以dp状态转移方程为\(dp[i][j]\, =\, max\left \{ {dp[i-1][k]} \right \} \, +\, w[i][j]\, \, (k\in [i-1,\, j-1])\)。

由于\(i\)只和\(i-1\)有关,可以使用滚动数组优化。去掉dp一个维度的同时,注意循环中\(k\)的方向要从后往前。最后在dp[\(F\)]中找到最大答案。

记录路径也很好实现。开个数组p[i][j]记录前驱。具体实现看代码。

#include<bits/stdc++.h>
using namespace std;
#define s(n) scanf("%d", &n)
int ed, num, dt=1, mx, v, f, ans, w[102][102], dp[102], p[102][102];
inline void pt(int a, int b){ //输出路径
if(a == 1){
printf("%d", b);
return;
}
pt(a-1, p[a][b]);
printf(" %d", b);
}
int main(){
s(f), s(v);
for(int i=1; i<=f; ++i) //读入数据
for(int j=1; j<=v; ++j)
s(w[i][j]);
for(int i=1; i<=f; ++i){
for(int j=v-f+i; j>=i; --j){ //因为要自我滚动,所以从后往前循环
for(int z=i-1; z<j; ++z){
if(z == i-1) mx = dp[z], num = z;
else if(mx < dp[z]) mx = dp[z], num = z;
}
dp[j] = mx + w[i][j];
p[i][j] = num;
if(i == f){
if(dt) ans = dp[j], dt = 0, ed = j;
else if(ans <= dp[j]) ans = dp[j], ed = j; //注意 一定是小于等于 因为要靠前放
}
}
}
printf("%d\n", ans);
pt(f, ed); //输出路径
return 0;
}

the end

花店橱窗(线性DP)的更多相关文章

  1. 【洛谷P1854】花店橱窗 线性dp+路径输出

    题目大意:给定 N 个数字,编号分别从 1 - N,M 个位置,N 个数字按照相对大小顺序放在 M 个位置里,每个数放在每个位置上有一个对答案的贡献值,求一种摆放方式使得贡献值最大. 题解:一道典型的 ...

  2. CH5E02 [IOI1999]花店橱窗[暴力dp]

    众所周知,这个人太菜了,所以她又来切水题了. 显然设计状态表示第$i$朵花放第$j$瓶中的最大价值.然后瞎转移一波是n三方的,加个前缀max变成n方就水过去了. 当然这题可以搜索剪枝的. 虐lyd书上 ...

  3. CH5E02 花店橱窗【线性DP】

    5E02 花店橱窗 0x5E「动态规划」练习 背景 xq和他的老婆xz最近开了一家花店,他们准备把店里最好看的花都摆在橱窗里.但是他们有很多花瓶,每个花瓶都具有各自的特点,因此,当各个花瓶中放入不同的 ...

  4. AcWing 313. 花店橱窗 (线性DP)打卡

    题目:https://www.acwing.com/problem/content/315/ 题意:有一个矩阵,你需要在每一行选择一个数,必须保证前一行的数的下标选择在下一行的左边,即下标有单调性,然 ...

  5. [IOI1999]花店橱窗布置(DP路径记录)

    题目:[IOI1999]花店橱窗布置 问题编号:496 题目描述 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定的,从左到右按1到V顺序编号,V ...

  6. 线性dp

    线性dp应该是dp中比较简单的一类,不过也有难的.(矩乘优化递推请出门右转) 线性dp一般是用前面的状态去推后面的,也有用后面往前面推的,这时候把循环顺序倒一倒就行了.如果有的题又要从前往后推又要从后 ...

  7. 花店橱窗(flower)

    花店橱窗(flower) 题目描述 某花店现有f束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定的,从左到右按1到V顺序编号,V是花瓶的数目.花束可以移动,并 ...

  8. 洛谷P1854 花店橱窗布置 分析+题解代码

    洛谷P1854 花店橱窗布置 分析+题解代码 蒟蒻的第一道提高+/省选-,纪念一下. 题目描述: 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定 ...

  9. [JOYOI] 1124 花店橱窗

    题目限制 时间限制 内存限制 评测方式 题目来源 1000ms 131072KiB 标准比较器 Local 题目背景 xq和他的老婆xz最近开了一家花店,他们准备把店里最好看的花都摆在橱窗里.但是他们 ...

  10. RQNOJ PID496/[IOI1999]花店橱窗布置

    PID496 / [IOI1999]花店橱窗布置 ☆   题目描述 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定的,从左到右按1到V顺序 编号 ...

随机推荐

  1. Windows CSC提权漏洞复现(CVE-2024-26229)

    漏洞信息 Windows CSC服务特权提升漏洞. 当程序向缓冲区写入的数据超出其处理能力时,就会发生基于堆的缓冲区溢出,从而导致多余的数据溢出到相邻的内存区域.这种溢出会损坏内存,并可能使攻击者能够 ...

  2. 【UnityTips】如何自定义脚本模版

    [UnityTips]如何自定义脚本模版 通常我们创建新脚本时大家看到的是这个样子: using System.Collections; using System.Collections.Generi ...

  3. AWX+gitlab

    目录 AWX+gitlab 1. Awx配置 1.1 添加机构 1.2 添加团队 1.3 添加主机 1.4 测试主机连通性 2. 对接gitlab 2.1 添加凭证 2.2 添加项目 2.3 上传pl ...

  4. Kubernetes(K8s)之Pod

    Pod介绍 Pod是K8s的最小调度单位 内部是一组Container容器,根容器Pause和其他业务容器 拥有唯一Pod IP 小贴士: 在生产环境中,极少单独Pod的情况 一般都是使用Deploy ...

  5. .NET下 支持大小写不敏感的JSON Schema验证方法

    问题 有很多应用程序在验证JSON数据的时候用到了JSON Schema. 在微服务架构下,有时候各个微服务由于各种历史原因,它们所生成的数据对JSON Object属性名的大小写规则可能并不统一,它 ...

  6. 基于.NET Core + Jquery实现文件断点分片上传

    基于.NET Core + Jquery实现文件断点分片上传 前言 该项目是基于.NET Core 和 Jquery实现的文件分片上传,没有经过测试,因为博主没有那么大的文件去测试,目前上传2G左右的 ...

  7. Android JACK 编译错误SSL error when connecting to the Jack server

    背景 之前编译好好,今天居然遇到了这样子的问题.还以为是和之前一样,Android7.0 配置JACK支持多用户同时编译. 结果不是: /bin/bash -c "(prebuilts/sd ...

  8. 一款利用人工智能将自然语言查询转换为 SQL 代码的互译工具 - SQL Translator

    前言 对于后端程序员来说,编写SQL代码是日常工作中不可或缺的一部分.然而,随着数据复杂性的增加,如何高效.准确地编写SQL查询成为了新的挑战.幸运的是,SQL Translator的出现为后端程序员 ...

  9. Python使用Argparse读取命令参数

    python编写的脚本需要通过命令参数来做一些参数配置.本文将介绍如何使用argparse来解析命令行参数.这种方法相对于sys.args的方式会简单很多. 通过以下的脚本来构建一个简单的配置解析器, ...

  10. 一次Java服务内存过高的分析过程

    现象 年前,收到了短信报警,显示A服务的某台机器内存过高,超过80% 如上图所示,内存会阶段性增加.奇怪的是,十多台机器中只有这一台有这个问题 堆内内存分析 最先怀疑是内存泄漏的问题,所以首先使用jm ...