題目描述:
假設你想以最美觀的方式布置花店的櫥窗。現在你有f束不同品種的花束,同時你也有至少同樣數量的花瓶被按順序擺成一行。這些花瓶的位置固定於架子上,並從1至v順序編號,v是花瓶的數目,從左至右排列,則最左邊的是花瓶1,最右邊的是花瓶v。花束可以移動,並且每束花用1至f間的整數唯一標識。標識花束的整數決定了花束在花瓶中的順序,如果i<j,則令花束i必須放在花束j左邊的花瓶中。 例如,假設一束杜鵑花的標識數為1,一束秋海棠的標識數為2,一束康乃馨的標識數為3,所有的花束在放入花瓶時必須保持其標識數的順序,即:杜鵑花必須放在秋海棠左邊的花瓶中,秋海棠必須放在康乃馨左邊的花瓶中。如果花瓶的數目大於花束的數目。則多餘的花瓶必須空置,且每個花瓶中只能放一束花。 每乙個花瓶都具有各自的特點。因此,當各個花瓶中放入不同的花束時,會產生不同的美學效果,並以美學值(乙個整數)來表示,空置花瓶的美學值為零。 在上述例子中,花瓶與花束的不同搭配所具有的美學值,如下表所示。
花瓶編號12
345杜鵑花723
-5-24
16秋海棠521
-410
23康乃馨
-215
-4-20
20例如,根據上表,杜鵑花放在花瓶2中,會顯得非常好看;但若放在花瓶4中則顯得十分難看。 為取得最佳美學效果,你必須在保持花束順序的前提下,使花束的擺放取得最大的美學值。如果有不止一種的擺放方式具有最大的美學值,你只要輸出字典序最小的那種擺放方式。
分析:這道題其實很明顯是一道dp題。
我們不妨設dp[i][j]表示前i束花放在第j個瓶(或最大為j編號的瓶)中的最大美學值。
那麼我們便可以用三重迴圈列舉,第一重迴圈列舉花束,第二重迴圈列舉瓶數,第三重迴圈列舉之前的花瓶
那麼我們便可以得到以下方程
dp[i][j]=max(dp[i][j],dp[i-1]][k]+a[i][j]);//k為之前的花瓶
那麼我們這裡還有乙個問題:如何輸出瓶數?
這裡,我們需要乙個陣列x,表示在dp的最有值得情況下的瓶子下標
對這個陣列進行一系列處理便可
那麼具體**如下:
#includeusing namespace std;
int main();//表示前i束花放在最大編號為j的瓶中的最大美學值
int x[101][101]={};//記錄相應瓶號
int a[101][101]={};
int x1[10001]={};
int n,m;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for (int i=1;i<=n;i++) dp[1][i]=a[1][i];//初始化
for (int i=2;i<=n;i++)
for (int j=i;j<=m-n+i;j++)//至少到第i個花瓶
for (int k=i-1;k<=j-1;k++)
if (dp[i-1][k]+a[i][j]>dp[i][j])
int maxx=0,k;
for (int i=n;i<=m;i++)
if (dp[n][i]>maxx)//尋找最大值
printf("%d\n",maxx);
for (int i=1;i<=n;i++)
x1[i]=k,k=x[n-i+1][k];//找出瓶子
printf("%d",x1[n]);
for (int i=n-1;i>=1;i--)
printf(" %d",x1[i]);//md我怎麼也想不到卡了我半年的錯誤竟然是空格。。。
return 0;
}
花店櫥窗布置 題解
櫥窗布置 description 假設以最美觀的方式布置花店的櫥窗,有f束花,每束花的品種都不一樣,同時,至少有同樣數量的花瓶,被按順序擺成一行,花瓶的位置是固定的,並從左到右,從1到v順序編號,v是花瓶的數目,編號為1的花瓶在最左邊,編號為v的花瓶在最右邊,花束可以移動,並且每束花用1到f的整數惟...
IOI 花店櫥窗
ioi 花店櫥窗 2017年8月14日 dp 遞迴輸出解決方案 假設你想以最美觀的方式布置花店的櫥窗。現在你有f束不同品種的花束,同時你也有至少同樣數量的花瓶被按順序擺成一行。這些花瓶的位置固定於架子上,並從1至v順序編號,v是花瓶的數目,從左至右排列,則最左邊的是花瓶1,最右邊的是花瓶v。花束可以...
花店櫥窗布置
題目描述 某花店現有f束花,每一束花的品種都不一樣,同時至少有同樣數量的花瓶,被按順序擺成一行,花瓶的位置是固定的,從左到右按1到v順序編號,v是花瓶的數目。花束可以移動,並且每束花用1到f的整數標識。如果i j,則花束i必須放在花束j左邊的花瓶中。例如,假設杜鵑花的標識數為1,秋海棠的標識數為2,...