5E02 花店橱窗 0x5E「动态规划」练习
背景
xq和他的老婆xz最近开了一家花店,他们准备把店里最好看的花都摆在橱窗里。但是他们有很多花瓶,每个花瓶都具有各自的特点,因此,当各个花瓶中放入不同的花束时,会产生不同的美学效果。为了使橱窗里的花摆放的最合适,他们得想个办法安排每种花的摆放位置。
可是因为xq和xz每天都太忙,没有时间设计橱窗里花的摆法,所以他们想让你帮他们求出花摆放的最大美观程度和每种花所放的位置。
描述
每种花都有一个标识,假设杜鹃花的标识数为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,表示xq和xz一共有F种花,V个花瓶。(1<=F<=V<=100)
第2行到第F+1行:每行有V个数,表示花摆放在不同花瓶里的美观程度值value。(美观程度和不超过maxint,美观程度有正有负)
输出格式
输出有两行:第一行为输出最大美观程度和的值,第二行有F个数表示每朵花应该摆放的花瓶的编号。若有多种方案,输出字典序较小的(美观程度不变的情况下,花尽量往前放)
样例输入
3 5 7 23 -5 -24 16 5 21 -4 10 23 -21 5 -4 -20 20
样例输出
53 2 4 5
题意:
有f种花,v个花瓶。每种花放在不同的花瓶得到的beauty值是不同的,给出这个价值矩阵。摆放花的顺序不可以改变,即花的序号是递增的。现在问一个方案,使得beauty之和是最大的。输出方案。
思路:
原来的思路是 用dp[i][j]表示前j个花瓶摆了i种花,用j作为阶段。但是这样好像不是很好输出路径。
应该用dp[i][j]表示第i种花放在第j个花瓶。然后枚举k,表示第i-1种花放在第k个花瓶。
1 //#include <bits/stdc++.h> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<stdio.h> 6 #include<cstring> 7 #include<vector> 8 #include<map> 9 10 #define inf 0x3f3f3f3f 11 using namespace std; 12 typedef long long LL; 13 14 int f, v; 15 int val[105][105], dp[105][105], path[105][105], res[105]; 16 17 18 int main() 19 { 20 scanf("%d%d", &f, &v); 21 for(int i = 1; i <= f; i++){ 22 for(int j = 1; j <= v; j++){ 23 scanf("%d", &val[i][j]); 24 } 25 } 26 27 memset(dp, -inf, sizeof(dp)); 28 for(int i = 1; i <= v; i++){ 29 dp[1][i] = val[1][i]; 30 } 31 for(int i = 2; i <= f; i++){ 32 for(int j = i; j <= v - (f - i); j++){ 33 for(int k = i - 1; k < j; k++){ 34 if(dp[i - 1][k] > dp[i][j]){ 35 dp[i][j] = dp[i - 1][k]; 36 path[i][j] = k; 37 } 38 } 39 dp[i][j] += val[i][j]; 40 } 41 } 42 43 int pos, ans = -inf; 44 for(int i = v - f; i <= v; i++){ 45 if(dp[f][i] > ans){ 46 ans = dp[f][i]; 47 pos = i; 48 } 49 } 50 printf("%d ", ans); 51 res[f] = pos; 52 for(int i = f - 1; i >= 1; i--){ 53 res[i] = path[i + 1][res[i + 1]]; 54 } 55 printf("%d", res[1]); 56 for(int i = 2; i <= f; i++){ 57 printf(" %d", res[i]); 58 } 59 printf(" "); 60 return 0; 61 }