题意:给定上一棵树和一个排列,然后问你把这个排列分成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. Pgsql和Mysql的对比

    工作中用过这两个数据库,但都不是太深入,仅限于用而已,但给我留下的印象就是Pgsql更好些,因为这两个库我都遇到过数据丢失的问题,前者我通过网上方法加自己的判断有惊无险的恢复了,而后者搜索各种资料加问 ...

  2. android adb端口被占用解决方法

    1.输入adb devices命令 C:\Users\Nick>adb devices List of devices attached adb server version (31) does ...

  3. TS流解析 三

    应该说真正了解TS,还是看了朋友推荐的<数字电视业务信息及其编码>一书之后,MPEG2 TS和数字电视是紧密不可分割的,值得总结一下其中的一些关系. ISO/IEC-13818-1:系统部 ...

  4. 【转】深入理解Java的接口和抽象类

    深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...

  5. Monkey记录

    1.查找包名方法 方法一: sdk里面的appt 以ES文件浏览器为例,命令行中切换到aapt.exe目录执行:aapt dump badging E:\apk\es3.apk 方法二: 查看data ...

  6. Jenkins构建Python项目提示:'python' 不是内部或外部命令,也不是可运行的程序

    问题描述: jenkin集成python项目,立即构建后,发现未执行成功,查看Console Output 提示:'Python' 不是内部或外部命令,也不是可运行的程序,如下图: 1.在 Windo ...

  7. 安装 sass 文档

    为什么使用Sass 作为前端(html.javascript.css)的三大马车之一的css,一直以静态语言存在,HTML5火遍大江南北了.javascript由于NODE.JS而成为目前前后端统一开 ...

  8. Python——截取web网页长图

    # -*- coding: utf8 -*-import timeimport xlrdfrom selenium import webdriver def read_excel(filename): ...

  9. mysql之SQLYog配置

    SQLyog(MySQL图形化开发工具) 安装: 提供的SQLyog软件为免安装版,可直接使用 使用: 输入用户名.密码,点击连接按钮,进行访问MySQL数据库进行操作

  10. linux中grep工具

    正则表达式 以前我们用grep在一个文件中找出包含某些字符串的行,比如在头文件中找出一个宏定义.其实grep还可以找出符合某个模式(Pattern)的一类字符串.例如找出所有符合xxxxx@xxxx. ...