P1854 花店櫥窗布置


P1854 花店櫥窗布置

時間限制: 1 Sec   內存限制: 64 MB

題目描述

假設你想以最美觀的方式布置花店的櫥窗。你有F束花,每束花的品種都不一樣,同時,你至少有同樣數量的花瓶,被按順序擺成一行。花瓶的位置是固定的,並從左至右,從1至V順序編號,V是花瓶的數目,編號為1的花瓶在最左邊,編號為V的花瓶在最右邊。花束則可以移動,並且每束花用1至F的整數唯一標識。標識花束的整數決定了花束在花瓶中排列的順序,即如果I<j,則花束I必須放在花束j左邊的花瓶中。

例如,假設杜鵑花的標識數為1,秋海棠的標識數為2,康乃馨的標識數為3,所有的花束在放入花瓶時必須保持其標識數的順序,即:杜鵑花必須放在秋海棠左邊的花瓶中,秋海棠必須入在康乃馨左邊的花瓶中,如果花瓶的數目大於花束的數目,則多余的花瓶必須空置,每個花瓶中只能放一束花。每一個花瓶的形狀和顏色也不相同。因此,當各個花瓶中放入不同的花束時,會產生不同的美學效果,並以美學值(一個整數)來表示,空置花瓶的美學值為零。在上述例子中,花瓶與花束的不同搭配所具有的美學值,可以用下面式樣的表格來表示

                 花瓶1 花瓶2 花瓶3 花瓶4 花瓶5

杜鵑花        7           23       -5      -24      16

秋海棠        5           21       -4       10       23

康乃馨      -21           5    -4      -20      20

例如,根據上表,杜鵑花放在花瓶2中,會顯得非常好看;但若放在花瓶4中則顯得很難看。
為取得最佳美學效果,你必須在保持花束順序的前提下,使花束的擺放取得最大的美學值。如果具有最大美學值的擺放方式不止一種,則其中任何一種擺放方式都可以接受,但你只輸出花瓶編號最靠前一種擺放方式。
假設條件(Asumption)
1≤F≤100,其中F為花束的數量,花束編號從1至F。
F≤V≤100,其中V是花瓶的數量。

-50Aij50,其中Aij 是花束i在花瓶j中時的美學值。

輸入

第1行:2個空格分開的整數f(1<=f<=100)和v(f<=v<=100),f表示花束的數量,v表示花瓶的數量第2..f+1行:每行v個空格分開的整數,第i+1行第j列的整數表示第i種花插在第j個花瓶里的美學值。

輸出

第1行:1個數表示擺放方案的最佳美學值。第2行:f個用1個空格分開的數,第i個數表示花束i所在的花瓶的編號。

樣例輸入

 (如果復制到控制台無換行,可以先粘貼到文本編輯器,再復制)

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

樣例輸出

53
2 4 5


這是洛谷上的一道題,戳我查看

—————————————————————————— 分析 ————————————————————————————

首先,我們先確定一下這道題目的意思。

所謂美學值最大,也就是一條從上至下的路徑沿途的數字最大,而且這些路徑滿足一個條件,行號較小的數的列號小於行號較大的數的列號。是不是有點類似於“數字三角形”,只是從上至下的過程中要保證列號越來越大,且一定要走到底。點擊查看數字三角形I

題目的意思弄懂了,那么我們如何找路徑呢?

我們可以自底向上求,然后在第1行找出最大值即可。值得交代的是過程。


從低向上求的第一層循環:for(i=n(花的數量)-1;i>=1;i--)

讓我們來分析一下第二層循環:因為所有的花束在放入花瓶時必須保持其標識數的順序,所以要給前面的花留位置,所以j必須要從i開始,不能從1開始。又因為后面也有數,所以我們定義一個m(m的初值為v,v為花瓶數),然后先讓m--,j<=m。
所以第二層循環就是:for(j=i;j<=m;j++)

然后是第三層循環,第三層循環的含義就是往i行j列的一個數下一行找一個最大的數。話不多說,意思都懂:
for(k=j+1(因為這個數的下一行必須大於這個數);k<=m+1(下一行的m是m))

順帶一提霍,有一個max_element函數對這道題有幫助,不知道的童鞋可以戳我查看

—————————————————————————— 代碼實現————————————————
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,v,a[105][105],Max,m,t,ans[105][105],p,K,i,j,P;
int main()
{
scanf("%d%d",&n,&v);
for(i=1;i<=n;i++)
for(j=1;j<=v;j++)
scanf("%d",&a[i][j]);

for(i=1;i<=v;i++) ans[i][n]=i;
m=v,p=n;
for(i=n-1;i>=1;i--)
{
m--;
p--;
for(j=i;j<=m;j++)
{
Max=-100;
for(int k=j+1;k<=m+1;k++)
if(a[i+1][k]>Max) Max=a[i+1][k],t=k;
a[i][j]+=Max,ans[j][p]=t;
}
}
printf("%d\n",*max_element(a[1]+1,a[1]+m+1));
K=max_element(a[1]+1,a[1]+m+1)-a[1];
printf("%d",K);
P=ans[K][1];
for(i=1;i<n;i++)
{
printf(" %d",P);
P=ans[P][i+1];
}
return 0;
}



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com