2015Daejeon UVALive 7236 K - Tree Edit
来源:互联网 发布:小约翰 震惊 知乎 编辑:程序博客网 时间:2024/05/22 14:53
题目描述:
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=104527#problem/K
题解:
原始树 叫 1 上面的节点为i 目标树叫2 节点为j
dp[i][j] 就是i节点和j节点到时候对应所花的目前的次数
然后树形dp
现在看dfs(i, j)怎么算 算出来的结果放到dp[i][j]中
设i的儿子a个 j b 个儿子,
那么我们用dp来算这一层,应该有f[a][b]个状态. 代表1树处理到a ,2树处理到b时的花费的次数. f的转移是o(1)的
看起来是一个n^4的dp
但是其实不是. 看每个节点被算了几次
只有往他父亲推的那一次才会被算一次, 算的复杂度上限是另外一棵树的节点个数
也可以说是每个i j 二元组只会被算一次,所以是n^2的
重点:
1.dp定状态暴力的思路很显然.
2.每一层相当于两个序列去对应的想法,用dp
3.复杂度的分析
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <vector>using namespace std;const int maxn = 1000 + 100;const int INF = 1e8;int n, m, f[maxn][maxn], dp[maxn][maxn], num[2][maxn];char lab[2][maxn];vector<int> G[2][maxn];char s[maxn * maxn];int cnt;void dfs_pre(vector<int> G[], int u, int num[]) { num[u] = 1; for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; dfs_pre(G, v, num); num[u] += num[v]; }}void dfs(int u, int v) { int ans = 0; if(lab[0][u] != lab[1][v]) ans++; for(int i = 0; i < G[0][u].size(); i++) { for(int j = 0; j < G[1][v].size(); j++) { dfs(G[0][u][i], G[1][v][j]); } } int tmp = INF; f[0][0] = 0; for(int i = 0; i <= G[0][u].size(); i++) { for(int j = 0; j <= G[1][v].size(); j++) { if(i ==0 && j == 0) continue; int id[2]; if(i != 0) id[0] = G[0][u][i - 1]; if(j != 0) id[1] = G[1][v][j - 1]; if(i == 0) { f[i][j] = f[i][j - 1] + num[1][id[1]]; } else if(j == 0) { f[i][j] = f[i - 1][j] + num[0][id[0]]; continue; } else { f[i][j] = f[i - 1][j - 1] + dp[id[0]][id[1]]; f[i][j] = min(f[i][j], f[i-1][j] + num[0][id[0]]); f[i][j] = min(f[i][j], f[i][j - 1] + num[1][id[1]]); } } } ans += f[G[0][u].size()][G[1][v].size()]; dp[u][v] = ans;}void solve() { dfs_pre(G[0], 1, num[0]); dfs_pre(G[1], 1, num[1]); dfs(1, 1); printf("%d\n", dp[1][1]);}int initail(int pos, vector<int> G[], char lab[]) { cnt++; lab[cnt] = s[pos]; int u = cnt; int i = pos + 1; while(s[i] != ')') { G[u].push_back(cnt+1); i = initail(i + 1, G, lab); } return i + 1;}void dfs_out(int u, vector<int> G[], char lab[]) { printf("%c :\n", lab[u]); for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; printf("%c ", lab[v]); } printf("\n"); for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; dfs_out(v, G, lab); }}int main() { //freopen("k.txt", "r", stdin); int ncase; scanf("%d", &ncase); while(ncase--) { for(int i = 1; i <= 1000; i++) { G[0][i].clear(); G[1][i].clear(); } scanf("%s", s); cnt = 0; initail(1, G[0], lab[0]); //printf("11 %d\n", G[0][1].size()); //dfs_out(1, G[0], lab[0]); scanf("%s", s); cnt = 0; initail(1, G[1], lab[1]); solve(); } return 0;}
0 0
- 2015Daejeon UVALive 7236 K - Tree Edit
- Regionals 2015 Asia - Daejeon acmliveoj7233 - Polynomial
- Regionals 2015 :: Asia - Daejeon A题
- Recover Binary Search Tree & Edit Distance & Reverse Nodes in k-Group
- tree edit distance
- UVALive 6669 Hidden Tree DP
- UVALive 5873 - Tree Inspections 【模拟】
- Regionals 2011, Asia - Daejeon
- Regionals 2014 Asia - Daejeon
- UVALive 5913 【NEERC 2011 K】 Kingdom Roadmap
- UVALive 2531 The K-League 最大流
- [蓝书/Ch5] The K-League UVALive
- extJs tree add edit delete js代码
- extJs tree add edit delete js代码
- k-d tree
- k-d tree算法
- K-D tree 数据结构
- k-d tree算法
- 并查集+欧拉回路
- ubuntu+opencv+qt小试牛刀2人脸识别
- bzoj3529: [Sdoi2014]数表
- win10在vbox虚拟机下运行
- 排序—基数排序(js实现)
- 2015Daejeon UVALive 7236 K - Tree Edit
- SOA的浅析
- Setting up Kafka
- 栈---链式存储
- 梵高
- JavaScript没有块级作用域
- MySQL系统函数
- C++11新特性应用--介绍几个新增的便利算法(stl中的heap使用,最大堆)
- iOS MD5加密 —— HERO博客