CH5E02 Solution

题目链接

题解

dp题呐。

状态:\(dp[i][j]\)表示前\(i\)种花使用\(i\)个花瓶得到的最大美观值。

初始值:\(dp[i][j]=-inf,dp[0][k]=0\quad (1\le i\le n,1\le j\le m,0\le k\le m)\)

答案可能是负数,初始值需要为极小值。

转移:\(dp[i][j]=min(dp[i-1][k]+v[i][j]))\quad(1\le i\le n,i\le j\le m,i-1\le k<j)\)

答案:\(ans=max(dp[n][i])\quad (n\le i\le m)\)

此外,此题需要输出方案,并且需要按照字典序输出,因此,题解作者写了长长的代码为了比较答案相同方案字典序(智商\(--\),快乐\(++\))。但是!\(i\)最小的\(dp[k][i]\)字典序也一定最小。设\(j\)满足\(j>i,dp[k][j]=dp[k][i]\),若\(v[k][j]\le v[k][i]\),则\(dp[k-1][j]\ge dp[k-1][i]\),因此\(i\le j\);若\(v[k][j]>v[k][i]\),则\(dp[k-1][j]<dp[k-1][i]\),但是\(dp[k][j]\)一定可以取到\(dp[k-1][i]\),因此\(dp[k][j]>dp[k][i]\),矛盾。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int v[N][N],dp[N][N],pre[N][N],qwq[N]; 
int main()
{
	int n,m,ans=0,pos;
	memset(dp,-0x3f,sizeof(dp));
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++) scanf("%d",&v[i][j]);
	for(int i=0;i<=m;i++) dp[0][i]=0;
	for(int i=1;i<=n;i++)
		for(int j=i;j<=m;j++)
			for(int k=i-1;k<j;k++) 
				if(dp[i][j]<dp[i-1][k]+v[i][j]) dp[i][j]=dp[i-1][k]+v[i][j],pre[i][j]=k;
	for(int i=1;i<=m;i++)
		if(dp[n][i]>ans) ans=dp[n][i],pos=i; 
	printf("%d\n",ans);
	for(int i=n;i>=1;i--) qwq[i]=pos,pos=pre[i][pos];
	for(int i=1;i<=n;i++) printf("%d ",qwq[i]);
	return 0;
}
posted @ 2021-03-05 22:05  violet_holmes  阅读(37)  评论(0编辑  收藏  举报