小 q 和他的老婆小 z 最近开了一家花店,他们准备把店里最好看的花都摆在橱窗里。
但是他们有很多花瓶,每个花瓶都具有各自的特点,因此,当各个花瓶中放入不同的花束时,会产生不同的美学效果。
为了使橱窗里的花摆放的最合适,他们得想个办法安排每种花的摆放位置。
可是因为小 q 和小 z 每天都太忙,没有时间设计橱窗里花的摆法,所以他们想让你帮他们求出花摆放的最大美观程度和每种花所放的位置。
每种花都有一个标识,假设杜鹃花的标识数为 1,秋海棠的标识数为 2,康乃馨的标识数为 3,所有的花束在放入花瓶时必须保持其标识数的顺序,即:
杜鹃花必须放在秋海棠左边的花瓶中,秋海棠必须放在康乃馨左边的花瓶中。
如果花瓶的数目大于花束的数目。则多余的花瓶必须空置,且每个花瓶中只能放一束花。
每种花放在不同的瓶子里会产生不同的美观程度,美观程度可能是正数也可能是负数。
上述例子中,花瓶与花束的不同搭配所具有的美观程度,如下表所示:
花 瓶
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 中则显得十分难看。
为取得最大美观程度,你必须在保持花束顺序的前提下,使花束的摆放取得最大的美学值,并求出每种花应该摆放的花瓶的编号。
输入格式
第 1 行:两个整数 F 和 V,表示共有 F 种花,V 个花瓶。
第 2 行到第 F+1 行:每行有 V 个数,表示花摆放在不同花瓶里的美观程度值 value。(美观程度和小于2^31,美观程度有正有负)
输出格式
输出有两行:第一行为输出最大美观程度和的值,第二行有 F 个数表示每朵花应该摆放的花瓶的编号。
若有多种方案,输出字典序较小的方案(美观程度不变的情况下,花尽量往前放)。
数据范围
1≤F≤V≤100,
输入样例:
3 5
7 23 -5 -24 16
5 21 -4 10 23
-21 5 -4 -20 20
输出样例:
53
2 4 5
题意: 给出一个n行m列的矩阵,现在每行选取1个数,如果当前行选取了第k个数,那么下一行就不能选前k个数,求最终选数加和的最大值,并输出字典序最小的方案。
分析: 设状态为dp[i][j]表示考虑前i行、前j列能选到的数的最大加和。在更新dp数组时dp[i][j]可以划分为两种情况,一种是选第i行第j列的数,一种是不选。对于选的情况应该从上一行上一列的状态转移,也就是dp[i][j] = dp[i-1][j-1]+a[i][j],而不选的情况就是dp[i][j-1],dp数组初始化的时候可以把第一行手动初始化,这样会比较稳一点。至于方案可以另开一个id数组,id[i][j]表示在前i行前j列选到最大值时第i行选择第几列,跟dp数组同步更新就行,最后输出方案时从后往前输出,id[n][m]就是最后一行的列,而id[n-1][id[n][m]-1]就是倒数第二行的列,以此类推。
具体代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#define int long long
using namespace std;
int n, m, a[105][105], dp[105][105], id[105][105];
const int inf = 1ll<<60;
signed main()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
dp[i][j] = -inf;
cin >> a[i][j];
}
dp[1][0] = -inf;
for(int i = 1; i <= m; i++){
dp[1][i] = dp[1][i-1];
id[1][i] = id[1][i-1];
if(dp[1][i] < a[1][i]){
dp[1][i] = a[1][i];
id[1][i] = i;
}
}
for(int i = 2; i <= n; i++)
for(int j = i; j <= m; j++){
dp[i][j] = dp[i][j-1];
id[i][j] = id[i][j-1];
if(dp[i][j] < dp[i-1][j-1]+a[i][j]){
dp[i][j] = dp[i-1][j-1]+a[i][j];
id[i][j] = j;
}
}
cout << dp[n][m] << endl;
int st[105], top = 0, r = m;
for(int i = n; i >= 1; i--){
st[++top] = id[i][r];
r = id[i][r]-1;
}
for(int i = top; i >= 1; i--)
cout << st[i] << " ";
return 0;
}
相关知识
[线性dp]花店橱窗 AcWing313
花店必备工具清单,准备开花店收好了!
开花店学习
花店装修不可忽视的10个细节
「花艺设计」以花为灵感|橱窗之美
家居花艺制作:用线性花材苋菜花制作一款瓶插花
这10个花店装修设计要点,你一定要了解
商场鲜花售卖橱窗
新手开花店丨花店装修设计需要注意哪些事项?
开花店知识丨花店综合管理,新手开店必知!
网址: [线性dp]花店橱窗 AcWing313 https://m.huajiangbk.com/newsview41575.html
上一篇: 花瓶鲜花ppt背景PPT模板素材 |
下一篇: 高花瓶适合插什么鲜花? |