RXD, tree and sequence IN HDU6065
解这道题绕了好多弯路。。。先是把"depth of the least common ancestor"这句话忽视掉,以为是最深点与最浅点的深度差;看到某人题解(的开头)之后发现自己理解错误,修改思路。结果又是绕好多弯路。构造了一个式子dp[i,j]其中i是前几个点,j是切分的段数。一直以为转移是整段转移(如果段是(1,5),直接dp[5,j]=dp[0,j-1]+val(1,5)),但是发现时间复杂度又过高,o(nk*n),之后改变了下思路,发现这题的整段真正有用的是最小深度那个核。
题意是把一串n排列切分成k段,让里面的数计算这些对应结点的最近公共祖先深度,之后求这个最小深度总和。如(1) (5 2 4 3),第1段是1的深度,第2段是min( dep(lca(5,2)) , dep(lca(2,4)) , dep(lca(4,3)) ),其中的核就是最小的那个deplca。
dp转移不需转移整段,可以空转移,只要保证加上那个核的权值之后跳到下一段就行,这样转移步幅小了很多(1~2),dp次数也降为o(nk)
dp[i,j]=dp[i-1,j](把i这个点当成对答案无关的跳过)dp[i-1,j-1](把i这个点当成对答案有关的核转移)dp[i-2,j-1](把i-1和i的最近公共祖先当成对答案有关的核转移)
这里的代码很无耻地借鉴了autsky-jadek的。。。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#define min(a,b) (a<b?a:b)
using namespace std;
typedef pair<int,int> Point;
const int N=;
int a[N],head[N],to[N<<],nxt[N<<],lca[N],fa[N],dep[N],ans[N],arc[N];
bool vis[N];
int n,k,u,v,en;
int dp[N+]; void addedge(int u,int v)
{
to[en]=v;
nxt[en]=head[u];
head[u]=en++;
}
int find_(int x){
return x==fa[x] ? x : fa[x]=find_(fa[x]);
}
void LCA(int u,int nowdeep)
{
ans[u]=u;
dep[u]=nowdeep;
for(int i=head[u];i!=-;i=nxt[i]) if(!dep[to[i]])
{
LCA(to[i],nowdeep+);
int f1=find_(u),f2=find_(to[i]);
fa[f1]=f2;
ans[find_(u)]=u;
}
vis[u]=true;
if(u!= && vis[u-])
lca[u-]=ans[find_(u-)];
if(u!=n- && vis[u+])
lca[u]=ans[find_(u+)];
}
int main()
{
int tmp,i;
while(scanf("%d%d",&n,&k)!=EOF)
{
en=;
memset(vis,,sizeof(vis));
memset(dep,,sizeof(dep));
memset(head,-,sizeof(head));
memset(dp,,sizeof(dp));
for(i=;i<n;i++)
{
scanf("%d",&tmp);
arc[tmp]=fa[i]=i;
}
for(i=;i<n;i++)
{
scanf("%d%d",&u,&v);
addedge(arc[u],arc[v]);addedge(arc[v],arc[u]);
}
LCA(arc[],);
for(i=;i<n-;++i)
lca[i]=dep[lca[i]];
for(i=;i<=n;++i)
{
int top=min(i,k);
for(int j=;j<=top;++j)
{
int nowans=;
if(j>&&i>)
nowans=min(nowans,dp[(i-)*(k+)+j-]+dep[i-]);
if(i->=&&j->=&&j-<=i-)
nowans=min(nowans,dp[(i-)*(k+)+j-]+lca[i-]);
if(j<=i-)
nowans=min(nowans,dp[(i-)*(k+)+j]);
dp[i*(k+)+j]=nowans;
}
}
printf("%d\n",dp[n*(k+)+k]);
}
return ;
}
tarjan离线,全局求祖先,顺带把相邻数字全查了
RXD, tree and sequence IN HDU6065的更多相关文章
- HDU 6065 RXD, tree and sequence (LCA DP)
RXD, tree and sequence Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java ...
- 【Tarjan】【LCA】【动态规划】【推导】hdu6065 RXD, tree and sequence
划分出来的每个区间的答案,其实就是连续两个的lca的最小值. 即5 2 3 4 这个区间的答案是min(dep(lca(5,2)),dep(lca(2,3),dep(lca(3,4)))). 于是dp ...
- HDU 6065 RXD, tree and sequence (LCA+DP)
题意:给定上一棵树和一个排列,然后问你把这个排列分成m个连续的部分,每个部分的大小的是两两相邻的LCA的最小深度,问你最小是多少. 析:首先这个肯定是DP,然后每个部分其实就是里面最小的那个LCA的深 ...
- hdu 6065 RXD, tree and sequence
题 OwO http://acm.hdu.edu.cn/showproblem.php?pid=6065 (2017 Multi-University Training Contest - Team ...
- ※数据结构※→☆非线性结构(tree)☆============二叉树 顺序存储结构(tree binary sequence)(十九)
二叉树 在计算机科学中,二叉树是每个结点最多有两个子树的有序树.通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree).二叉树常被用作二叉查找树和二叉堆或是 ...
- Java基础之泛型——使用二叉树进行排序(TryBinaryTree)
控制台程序. 1.实现针对容器类的基于集合的循环 为了让容器类类型的对象能够在基于集合的for循环中可用,类必须并且只需要满足一个要求——必须实现泛型接口java.lang.Iterable<& ...
- (04)odoo视图操作
-----------------更新时间19:04 2016-09-29 星期四11:17 2016-09-18 星期日18:13 2016-04-05 星期二15:05 2016-03-14 星期 ...
- awesome-nlp
awesome-nlp A curated list of resources dedicated to Natural Language Processing Maintainers - Keon ...
- 二叉树的Morris遍历
二叉树的遍历,除了上篇文章中的传统递归和使用的栈结构的非递归方式,还有如下这种Morris遍历方式,该算法的构思非常巧妙:利用前驱空闲的rightChild指针指向当前节点,形成一个环.时间复杂度和前 ...
随机推荐
- Reading List on Automated Program Repair
Some resources: https://www.monperrus.net/martin/automatic-software-repair 2017 [ ] DeepFix: Fixing ...
- OpenJDK和JDK区别
OpenJDK和JDK区别 OpenJDK与JDK的区别分析 Sun的JDK7.OpenJDK及IcedTea释疑 简介(ps): 简单来说jdk从7开始,弄出一个可以自由使用的公共版本(openjd ...
- MapReduce Map数 reduce数设置
JobConf.setNumMapTasks(n)是有意义的,结合block size会具体影响到map任务的个数,详见FileInputFormat.getSplits源码.假设没有设置mapred ...
- 七牛 qshell 全命令实践
七牛API服务的命名行测试工具,参考文档 七牛开发者中心 命令行工具(qshell) 实践目的 安装 account 设置ak.sk stat 查看文件状态 buckets/listbucket/do ...
- 15 VScode 使用相关
1.生成html头文件 ①:按下!键 ②:连按两下tab键 即可
- Python学习之旅(十八)
Python基础知识(17):面向对象编程(Ⅱ) 获取对象信息 在不知道对象信息的情况下,我们想要去获取对象信息,可以使用以下方法 1.type (1)判断对象类型 >>> type ...
- javascript数组的内置对象Array
javascript的内置对象Array是用于构造数组的全局对象,数组是类似于列表的高阶对象. 创建数组的方法: 1通过字面量:var arr = [1,2,3]; 里面的参数直接作为数组里的值 2通 ...
- 泡泡一分钟:Cubic Range Error Model for Stereo Vision with Illuminators
Cubic Range Error Model for Stereo Vision with Illuminators 带有照明器的双目视觉的三次范围误差模型 "链接:https://pan ...
- Gym 101873G - Water Testing - [皮克定理]
题目链接:http://codeforces.com/gym/101873/problem/G 题意: 在点阵上,给出 $N$ 个点的坐标(全部都是在格点上),将它们按顺序连接可以构成一个多边形,求该 ...
- Ubuntu 18.04安装JDK并配置环境变量
1.官网下载jdk 下载链接 http://www.oracle.com/technetwork/java/javase/downloads/index.html 可以根据自己的系统进行下载 2.进行 ...