1. 程式人生 > 其它 >櫥窗佈置(洛谷P1854)

櫥窗佈置(洛谷P1854)

https://www.luogu.com.cn/problem/P1854
問題實際就是給定F束花和V個花瓶,以及各束花放到不同花瓶中的美學值,要求你找出一種擺放的方案,使得在滿足編號小的花放進編號小的花瓶中的條件下,美學值達到最大。
將問題進行轉化,找出問題的原型。首先,看一下上述題目的樣例資料表格。
將擺放方案的要求用表格表現出來,則擺放方案需要滿足:每行選且只選一個數(花瓶);擺放方案的相鄰兩行中,下面一行的花瓶編號要大於上面一行的花瓶編號兩個條件。
這時可將問題轉化為:給定一個數字表格,要求程式設計計算從頂行至底行的一條路徑,使得這條路徑所經過的數字總和最大(要求每行選且僅選一個數字)。
同時,路徑中相鄰兩行的數字,必須保證下一行數字的列數大於上一行數字的列數。

看到經過轉化後的問題,發現問題與“數學三角形”問題十分相似,
因此也採用相似的寫法

標程程式碼
···cpp

include

include

include

using namespace std;
int main()
{
int a[101][101],b[101][101],c[101][101],d[101]; //a[i][j] 花束i放在花瓶j中的美學值
//b[i][j] 前i束花放在前j個花瓶中的最優解
//c[i][j] 在b[i][j]的最優解中,花束i-1的位置
int f,v,i,j,k,max; //f , v 花束和花瓶的數目
cin>>f>>v;
for (i=1;i<=f;i++)
for (j=1;j<=v;j++)
cin>>a[i][j];
memset(b,128,sizeof(b)); //這樣處理,可以保證每束花都放進花瓶
for (i=1;i<=v-f+1;i++) //初始化第1束花放在第i個花瓶的情況
b[1][i]=a[1][i];
for (i=2;i<=f;i++)
for (j=i;j<=v-f+i;j++)
for (k=i-1;k<=j-1;k++) //列舉花束i-1的位置
if (b[i-1][k]+a[i][j]>b[i][j])
{
b[i][j]=b[i-1][k]+a[i][j]; //更新當前最優解
c[i][j]=k; //前一個花束的位置為k
}
max=-2100000000;
for (i=f;i<=v;i++)
if (b[f][i]>max)
{
max=b[f][i]; //選擇全域性最優解
k=i; //k最後一束花的位置
}
cout<<max<<endl; //列印最優解
for (i=1;i<=f;i++)
{
d[i]=k;
k=c[f-i+1][k];
}
for (i=f;i>=2;i--)
cout<<d[i]<<" ";
cout<<d[1]<<endl;
}

我的寫法(區別是輸出路徑的方式一個是遞推一個是遞迴)
```cpp
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=1010;
int f,v;
int d[maxn][maxn];
int dp[maxn][maxn],pre[maxn][maxn];
void print(int x,int y)
{
    if(pre[x][y]==y)
	{ 
		printf("%d ",y); 
		return;
	}
    print(x-1,pre[x][y]);
    printf("%d ",y);
}
int main()
{
	scanf("%d%d", &f, &v);
    for(int i=1;i<=f;i++)
    {
    	
    	for(int j=1;j<=v;j++)
    	{	
			scanf("%d", &d[i][j]);
		}
	}
    for(int i=1;i<=v-f;i++)
	{
		dp[1][i]=d[1][i];
		pre[1][i]=i;
	}
	for(int i=2;i<=f;i++)
	{
		for(int j=i;j<=v-f+i;j++)
		{
			for(int k=1;k<j;k++)
			{
				if(dp[i-1][k]+d[i][j]>dp[i][j])
				{
					dp[i][j]=dp[i-1][k]+d[i][j];
					pre[i][j]=k;
				}
			}
		}
	}
	int tx=f,ty,ans=0;
    for(int i=f;i<=v;i++)
 	{
    	if(dp[f][i]>ans)
		{ 
			ans=dp[f][i]; 
			ty=i;
		}
	}
    printf("%d\n",ans);
    print(tx,ty);
    return 0;
}