【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

【BZOJ4254】Aerial Tramway 树形DP的更多相关文章

  1. BZOJ4254 : Aerial Tramway

    可以修建的缆车总数不超过n,于是可以先通过$O(n^2)$的枚举求出所有可以修建的缆车. 对于一个缆车,若它仅连接i和i+1,那么它不受k的限制,把这种缆车额外取出,从大到小排序. 剩下的缆车两两之间 ...

  2. 【刷题】BZOJ 4254 Aerial Tramway

    Description You own a park located on a mountain, which can be described as a sequence of n points ( ...

  3. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  4. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  5. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  6. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  7. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  8. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  9. POJ2342 树形dp

    原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...

随机推荐

  1. Jquery使容器自适应浏览器窗口

    一.几个关键点 1:当文档大小改变时可以通过哪个事件来触发? resize([Data], fn) 可传入data供函数fn处理. 示例: $(window).resize(function(){ a ...

  2. Apache重启报警,不存在虚拟主机目录(httpd.conf打开了一些扩展)

    Apache重启时报警: AH00112: Warning: DocumentRoot [/usr/local/apache/docs/dummy-host.example.com] does not ...

  3. 并发登录人数控制--Shiro系列(二)

    为了安全起见,同一个账号理应同时只能在一台设备上登录,后面登录的踢出前面登录的.用Shiro可以轻松实现此功能. shiro中sessionManager是专门作会话管理的,而sessinManage ...

  4. jquery获取元素索引值index()

    jquery获取元素索引值index()方法实例. jquery获取元素索引值index()方法: jquery的index()方法 搜索匹配的元素,并返回相应元素的索引值,从0开始计数. 如果不给 ...

  5. MySql图解给表添加外键

    关于外键约束的几种方式,请移步鄙人的另外一个博客中的博文  http://blog.csdn.net/hadues/article/details/52558184

  6. Node.js用fs.renameSync报cross-device link not permitted错

    转自: http://blog.csdn.net/starrexstar/article/details/8048722 今天把 Manuel Kiessling 的[The Node Beginne ...

  7. python 使用urllib.urlopen超时问题的解决方法

    准备写一个python脚本抓取网页数据,前面抓了几个都没有什么问题,但总会抓取不完整,在中间过程中没有反应,发现执行urlopen的地方总是提示超时,百度了一下,因为我使用的是urllib不是urll ...

  8. Python内置函数property()使用实例

    class Shuxing(): def __init__(self, size = 10): self.size = size def getSize(self): print('getSize') ...

  9. Bootstrap学习笔记(3)--菜鸟网CDN

    Bootstrap CDN 推荐 本站实例采用的是自建的静态资源库上的Bootstrap资源. <!-- 新 Bootstrap 核心 CSS 文件 --> <link href=& ...

  10. Unix系统编程()进程内存布局

    每个进程所分配的内存由很多部分组成,通常称之为"段(segment)". 文本段包含了进程运行的程序机器语言指令.文本段具有只读属性,以防止进程通过错误指针意外修改自身指令. 因为 ...