【BZOJ4254】Aerial Tramway 树形DP

【BZOJ4254】Aerial Tramway

题意:给你一座山上n点的坐标,让你在山里建m条缆车,要求缆车两端的高度必须相等,且中间经过的点的高度都小于缆车的高度。并且不能存在一个点位于至少k条缆车的下方。求缆车的最大总长度。

n,m<=200,k<=10。

题解:这么神奇的题面居然有人能想到要用树形DP。。。

先枚举所有可能的缆车,然后暴力得出这些缆车的关系。因为上面的缆车一定比它下面的缆车长,所以这形成了一个树形结构,我们建树跑树形DP。

用f[x][a][b]表示x的子树中已经减了y个缆车,且一个点最多位于k条缆车下方,的最大总长度。转移时是惯用的树形背包套路,然后用前缀最大值优化一下即可。时间复杂度O(n*m*k)。

 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
int T,n,m,K,tot,ans,cas;
int x[210],y[210],v[210],bel[210],siz[210],g[210][15],f[210][210][15],d[210];
vector<int> ch[210];
inline int rd()
{
	int ret=0,f=1;	char gc=getchar();
	while(gc<'0'||gc>'9')	{if(gc=='-')	f=-f;	gc=getchar();}
	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
	return ret*f;
}
void dfs(int x)
{
	siz[x]=1;
	int i,j,k,l,y;
	for(l=0;l<=K;l++)	f[x][0][l]=0;
	for(i=0;i<(int)ch[x].size();i++)
	{
		y=ch[x][i],dfs(y);
		memcpy(g,f[x],sizeof(f[x]));
		for(j=0;j<=siz[x]&&j<=m;j++)	for(k=0;k<=siz[y]&&j+k<=m;k++)	for(l=0;l<=K;l++)
			g[j+k][l]=max(g[j+k][l],f[x][j][l]+f[y][k][l]);
		siz[x]+=siz[y];
		for(j=0;j<=siz[x]&&j<=m;j++)	for(l=1;l<=K;l++)	f[x][j][l]=max(g[j][l],f[x][j][l-1]);
	}
	for(j=min(m,siz[x]);j>=1;j--)	for(l=1;l<=K;l++)
	{
		f[x][j][l]=max(f[x][j][l],f[x][j-1][l-1]+v[x]);
		f[x][j][l]=max(f[x][j][l],f[x][j][l-1]);
	}
	ans=max(ans,f[x][m][K]);
}
void work()
{
	tot=0,K--;
	int i,j;
	for(i=1;i<=n;i++)	x[i]=rd(),y[i]=rd(),ch[i].clear(),bel[i]=0;
	for(i=1;i<=n;i++)
	{
		for(j=i-1;j>=1;j--)
		{
			if(y[j]>y[i])	break;
			if(y[j]==y[i])
			{
				bel[i]=++tot,v[tot]=x[i]-x[j],d[tot]=0;
				break;
			}
		}
		if(y[j]==y[i]&&bel[i])	for(j++;j<i;j++)	if(y[j]<y[i]&&bel[j]&&!d[bel[j]])
			d[bel[j]]=1,ch[bel[i]].push_back(bel[j]);
	}
	memset(f,0xc0,sizeof(f));
	v[++tot]=-1<<20;
	for(i=1;i<tot;i++)	if(!d[i])	ch[tot].push_back(i);
	ans=-1,dfs(tot);
	printf("%d\n",ans);
}
int main()
{
	while(scanf("%d%d%d",&n,&m,&K)!=EOF)
	{
		printf("Case %d: ",++cas);
		work();
	}
	return 0;
}//14 3 3 1 8 2 6 3 4 4 6 5 3 6 4 7 1 8 4 9 6 10 4 11 6 12 5 13 6 14 8 14 3 2 1 8 2 6 3 4 4 6 5 3 6 4 7 1 8 4 9 6 10 4 11 6 12 5 13 6 14 8 

 

posted @ 2017-10-29 10:18  CQzhangyu  阅读(280)  评论(0编辑  收藏  举报