【BZOJ-1369】Gem 树形DP】的更多相关文章

题目大意 给出一棵树,要求你为树上的结点标上权值,权值可以是任意的正整数 唯一的限制条件是相临的两个结点不能标上相同的权值,要求一种方案,使得整棵树的总价值最小.N<=10000 题解 我们可以猜一个结论,用到的编号不会超过某一个值 我们发现我们可以开到100以上都不会超时 所以我们把编号最多100算,跑树形dp即可 其实可以证明编号不会超过logn... Code #include <cstdio> #include <cstring> #include <algor…
传送门 解题思路 直接按奇偶层染色是错的,\(WA\)了好几次,所以要树形\(dp\),感觉最多\(log\)种颜色,不太会证. 代码 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int N=10005; inline int rd(){ int x=0,f=…
1369: [Baltic2003]Gem Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 282  Solved: 180[Submit][Status][Discuss] Description 给出一棵树,要求你为树上的结点标上权值,权值可以是任意的正整数 唯一的限制条件是相临的两个结点不能标上相同的权值,要求一种方案,使得整棵树的总价值最小. Input 先给出一个数字N,代表树上有N个点,N<=10000 下面N-1行,代表两个点相连 Out…
题目描述的实际是一颗二叉树,对于每个结点,要么满叉,要么无叉. 对于一种无解的简单情况,我们搜一遍树找到最浅的叶子结点1和最深的叶子结点2,如果dep[1]<dep[2]-1,则显然无解. 所以现在所有的叶子结点的深度要么是dep[1]和dep[2]. 我们可以把所有结点用node[x]标记状态. node[x]=0表示x的子树下所有叶子结点深度都是dep[2]. node[x]=1表示x的子树下一部分叶子结点深度是dep[1],一部分是dep[2]. node[x]=2表示x的子树下所有叶子结…
题目描述 给出一棵树,要求你为树上的结点标上权值,权值可以是任意的正整数 唯一的限制条件是相临的两个结点不能标上相同的权值,要求一种方案,使得整棵树的总价值最小. 输入 先给出一个数字N,代表树上有N个点,N<=10000 下面N-1行,代表两个点相连 输出 最小的总权值 样例输入 10 7 5 1 2 1 7 8 9 4 1 9 7 5 6 10 2 9 3 样例输出 14 题解 树形dp f[i][j]表示第i个点权值为j时i的子树的最小权值和. 一开始以为颜色数最多有n种,n^3的dp算法…
问题描述 LG4395 BZOJ1369 题解 发现对于结点 \(x\) ,其父亲,自己,和所有的孩子权值不同,共 \(3\) 类,从贪心的角度考虑,肯定是填 \(1,2,3\) 这三种. 于是套路树形DP,设 \(opt[x][1/2/3]\) 代表以 \(x\) 为根的子树中,且 \(x\) 标为 \(0/1/2\) 的最小值. \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace std; template <typen…
结论 不同颜色数不会超过 \(O(\log n)\) 然后就是很简单的树形dp了 顺便复习一下树形dp怎么写 #include <bits/stdc++.h> using namespace std; int f[10005][20]; vector<int> g[10005]; int n,t1,t2,vis[10005]; void dfs(int p) { vis[p]=1; for(int i=0;i<g[p].size();i++) { int q=g[p][i];…
传送门 题目大意: 给一棵树上每个点一个正权值,要求父子的权值不同,问该树的最小权值和是多少. 题目分析: 证不出来最少染色数,那就直接信仰用20来dp吧:dp[u][i]表示u节点权值赋为i时u子树的权值最小值,\[dp[u][i] = \sum{max\{dp[v][j]\}} + i (i != j)\]. code #include<bits/stdc++.h> using namespace std; #define maxn 10050 #define oo 0x3f3f3f3f…
3090: Coci2009 [podjela] Description 有 N 个农民, 他们住在 N 个不同的村子里. 这 N 个村子形成一棵树.每个农民初始时获得 X 的钱.每一次操作, 一个农民可以从它自己的钱中, 取出任意数量的钱, 交给某个相邻村子的农民. 对于每个农民给定一个值 v_i, 求    (1) 最少需要多少次操作, 使得每个农民最终拿到的钱 >= 给定的值. Input 第1行: 一个整数 N (1 <= N <= 2000)    第2行: 一个整数 X (0…
思路:随便想想就能想出来啦把...  卡了我一个vector... #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int,int> #define piii pair<int, pair<int,int> > using namespace std; ; + ; cons…