题意:给定上一棵树和一个排列,然后问你把这个排列分成m个连续的部分,每个部分的大小的是两两相邻的LCA的最小深度,问你最小是多少。

析:首先这个肯定是DP,然后每个部分其实就是里面最小的那个LCA的深度。很容易知道某个区间的值肯定是 [li, li+1] .. [ri-1, ri]这些区间之间的一个,并且我们还可以知道,举个例子,1 2 3 4  5 6 如果知道分成两部分 其中 2 和 6 是最优的,那么中间的 3 4 5 ,这三个数其实属于哪个区间都无所谓,所以对于第 i 个数只有三种可能。

dp[i[j] 表示前 i 个数分成 j 个区间

第一种:它自己属于单独的区间,dp[i][j] = min{ dp[i-1][j-1] + deep[a[i]] }

第二种:它和前面那个数属于一个区间,dp[i][j] = min{ dp[i-2][j-1] + deep[lca(a[i], a[i-1])] }

第三种:它对任何区间都没有贡献,那么无所谓了 dp[i][j] = min{ dp[i-1][j] }

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define pu push_up
#define pd push_down
#define cl clear()
//#define all 1,n,1
#define FOR(i,x,n) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 3e5 + 20;
const int maxm = 100 + 10;
const ULL mod = 10007;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, -1, 0, 1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r >= 0 && r < n && c >= 0 && c < m;
} struct Edge{
int to, next;
};
Edge edge[maxn<<1];
int head[maxn], cnt; void addEdge(int u, int v){
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
} int a[maxn];
int dp[3][maxn];
int dep[maxn], p[20][maxn];
void dfs(int u, int fa, int d){
dep[u] = d;
p[0][u] = fa;
for(int i = head[u]; ~i; i = edge[i].next){
int v = edge[i].to;
if(v == fa) continue;
dfs(v, u, d + 1);
}
} void init(){
ms(p, -1);
dfs(1, -1, 1);
FOR(k, 0, 19) for(int v = 1; v <= n; ++v){
if(p[k][v] < 0) p[k+1][v] = -1;
else p[k+1][v] = p[k][p[k][v]];
}
} int LCA(int u, int v){
if(dep[u] > dep[v]) swap(u, v);
for(int k = 0; k < 20; ++k)
if(dep[v] - dep[u] >> k & 1) v = p[k][v];
if(u == v) return u;
for(int k = 19; k >= 0; --k)
if(p[k][u] != p[k][v]){
u = p[k][u];
v = p[k][v];
}
return p[0][u];
} int lca[maxn]; int main(){
while(scanf("%d %d", &n, &m) == 2){
for(int i = 1; i <= n; ++i) scanf("%d", a + i);
ms(head, -1); cnt = 0;
for(int i = 1; i < n; ++i){
int u, v;
scanf("%d %d", &u, &v);
addEdge(u, v);
addEdge(v, u);
}
init(); ms(dp, INF); lca[1] = dep[a[1]];
for(int i = 2; i <= n; ++i) lca[i] = dep[LCA(a[i], a[i-1])];
dp[0][0] = dp[1][0] = dp[2][0] = 0;
for(int i = 1; i <= n; ++i){
int t = min(i, m);
for(int j = 1; j <= t; ++j){
dp[i%3][j] = min(dp[(i-1)%3][j-1] + dep[a[i]], dp[(i-1)%3][j]);
if(i > 1) dp[i%3][j] = min(dp[i%3][j], dp[(i-2)%3][j-1] + lca[i]);
}
}
printf("%d\n", dp[n%3][m]);
}
return 0;
}

  

HDU 6065 RXD, tree and sequence (LCA+DP)的更多相关文章

  1. 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 ...

  2. hdu 6065 RXD, tree and sequence

    题 OwO http://acm.hdu.edu.cn/showproblem.php?pid=6065 (2017 Multi-University Training Contest - Team ...

  3. 【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 ...

  4. RXD, tree and sequence IN HDU6065

    解这道题绕了好多弯路...先是把"depth of the least common ancestor"这句话忽视掉,以为是最深点与最浅点的深度差:看到某人题解(的开头)之后发现自 ...

  5. HDU 6060 RXD and dividing(LCA)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6060 [题目大意] 给一个n个节点的树,要求将2-n号节点分成k部分, 然后将每一部分加上节点1, ...

  6. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

  7. HDU 5513 Efficient Tree

    HDU 5513 Efficient Tree 题意 给一个\(N \times M(N \le 800, M \le 7)\)矩形. 已知每个点\((i-1, j)\)和\((i,j-1)\)连边的 ...

  8. hdu 5025 Saving Tang Monk 状态压缩dp+广搜

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092939.html 题目链接:hdu 5025 Saving Tang Monk 状态压缩 ...

  9. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

随机推荐

  1. SonarQube使用教程

    SonarQube是管理代码质量一个开放平台,可以快速的定位代码中潜在的或者明显的错误,本文将会介绍一下这个工具的安装.配置以及使用. 一.SonarQube的安装使用: 下载地址:http://ww ...

  2. Shell编程时常用的系统文件(转)

    10.1 Linux系统目录结构 / 根目录,所有文件的第一级目录 /home 普通用户家目录 /root 超级用户家目录 /usr 用户命令.应用程序等目录 /var 应用数据.日志等目录 /lib ...

  3. WinForm各浏览器内核控件

    WebKit.NET webkit-sharp CefSharp awesomium OpenWebKitSharp geckofx MozNet Web Component

  4. Java--不可覆盖的方法

    私有方法不能被覆盖: 因为private被自动认为final,对子类是屏蔽的,那么子类中的相同方法就是一个新的方法,编译器不会报错但也不会按期望运行: public class ClassA { pr ...

  5. 原生态JDBC问题的总结

    package com.js.ai.modules.aiyq.testf; import java.sql.Connection; import java.sql.DriverManager; imp ...

  6. 性能基准测试:KVM大战Xen

    编译自:http://major.io/2014/06/22/performance-benchmarks-kvm-vs-xen/作者: Major Hayden原创:LCTT https://lin ...

  7. SpringBoot入门篇--对于JSON数据的返回以及处理一

    在后台的开发过程中不可避免的就是一系列对JSON数据的返回,需要我们进行的就是提供各种各样的数据.一般情况下数据类型最常用的就是JSON以及XML,在这里我们就讲讲在SpringBoot里面我们怎样进 ...

  8. 一个检测网页是否有日常链接的python脚本

    在大的互联网公司干技术的基本都会碰到测试.预发布.线上这种多套环境的,来实现测试和线上正式环境的隔离,这种情况下,就难免会碰到秀逗了把测试的链接发布到线上的情况,一般这种都是通过一些测试的检查工具来检 ...

  9. 一次使用 Redis 优化查询性能的实践

    因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,一次使用 Redis 优化查询性能的实践 应用背景 有一个应用需要上传一组ID到 ...

  10. echart改变legend样式及分页

    legend: { type: 'scroll', orient: 'horizontal', bottom:0, left:'center', itemGap: 0, itemWidth: 10, ...