橱窗布置(洛谷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;
}
posted @ 2021-06-19 18:31  Mint-hexagram  阅读(44)  评论(0编辑  收藏  举报