UVALive 6631|Jingle Balls|树形DP
2017-12-03 00:17
375 查看
题目大意
一棵树的叶节点一开始至多有一个球,要求移动最少数量的球使得对于每个节点其两子树的球的数量差至多为1。题目原文
It will soon be time to decorate the Christmas tree. The NWERC judges are already debating theoptimal way to put decorations in a tree. They agree that it is essential to distribute the decorations
evenly over the branches of the tree.
This problem is limited to binary Christmas trees. Such trees consist of a trunk, which splits into
two subtrees. Each subtree may itself split further into two smaller subtrees and so on. A subtree that
does not split any further is a twig. A twig may be decorated by attaching at most one ball to it.
Figure 1 — Example of a tree with subtrees, twigs and one ball.
A decorated tree has an even distribution of balls if and only if the following requirement is satisfied:
At every point where a (sub)tree splits into two smaller subtrees t1 and t2, the total number of balls
in the left subtree N(t1) and the total number of balls in the right subtree N(t2) must either be equal
or differ by one. That is: |N(t1) − N(t2)| ≤ 1.
In their enthusiasm, the judges initially attach balls to arbitrary twigs in the tree. When they can
not find any more balls to put in the tree, they stand back and consider the result. In most cases,
the distribution of the balls is not quite even. They decide to fix this by moving some of the balls to
different twigs.
Given the structure of the tree and the initial locations of the balls, calculate the minimum number
of balls that must be moved to achieve an even distribution as defined above.
Note that it is not allowed to add new balls to the tree or to permanently remove balls from the
tree. The only way in which the tree may be changed is by moving balls to different twigs.
输入
For each test case, the input consists of one line describing a decorated tree.The description of a tree consists of a recursive description of its subtrees. A (sub)tree is represented
by a string in one of the following forms:
• The string ‘()’ represents a twig without a ball.
• The string ‘(B)’ represents a twig with a ball attached to it.
• The string ‘(t1t2)’ represents a (sub)tree that splits into the two smaller subtrees represented by
t1 and t2, where t1 and t2 are strings in one of the forms listed here.
A tree contains at least 2 and at most 1000 twigs.
输出
For each test case, print one line of output.If it is possible to distribute the balls evenly through the tree, print the minimum number of balls
that must be moved to satisfy the requirement of even distribution.
If it is not possible to distribute the balls evenly, print the word ‘impossible’.
样例输入
((B)()) ((((B)(B))((B)()))(B)) (()(((B)(B))(B)))
样例输出
0 impossible 1
题解
显然是树形DP。令
f[i][j]表示第i个节点有j个球的最少移动球的个数。
那么显然如果i为叶节点时,如果i原来就有球,那么
f[i][1]=0,
f[i][0]=1比较显然。如果i原来没有球,那么
f[i][0]=f[i][1]=0。我们只需要算一次移动就可以了,如果
f[i][1]=1那么答案会翻倍。最终结果除2也可以。
那么对于非叶节点,如果j为奇数,那么
f[i][j]=\min\{f[left[i]][j/2]+f[right[i]][j/2+1],f[left[i]][j/2+1]+f[right[i]][j/2]\},因为差至多为1,那么只有2种情况。如果j为偶数,那么显然
f[i][j]=f[left[i]][j/2]+f[right[i]][j/2]
代码
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int inf = 1e9; const int N = 5005; // ball[] == -1 -> not a leaf. int ball , L , R , dp ; char str[32768]; int id, sum; void parse(char *str, int &t, int l, int r) { t = ++ id; if (l + 1 == r || l + 2 == r) { ball[t] = l + 2 == r; sum += ball[t]; return; } int x = 0, mid; for (mid = l + 1; mid < r; ++ mid) { if (str[mid] == '(') ++ x; if (str[mid] == ')') -- x; if (x == 0) break; } parse(str, L[t], l + 1, mid); parse(str, R[t], mid + 1, r - 1); } int solve(int t, int sum) { if (dp[t][sum] != -1) return dp[t][sum]; // if leaf if (ball[t] != -1) { if (sum > 1) dp[t][sum] = inf; else if (ball[t]) { // has initial ball dp[t][0] = 1; dp[t][1] = 0; } else { dp[t][0] = 0; dp[t][1] = 1; } return dp[t][sum]; } if (sum & 1) dp[t][sum] = min( solve(L[t], sum / 2) + solve(R[t], sum / 2 + 1), solve(L[t], sum / 2 + 1) + solve(R[t], sum / 2) ); else dp[t][sum] = solve(L[t], sum / 2) + solve(R[t], sum / 2); if (dp[t][sum] > inf) dp[t][sum] = inf; return dp[t][sum]; } int main() { while (scanf("%s", str + 1) != EOF) { int len = strlen(str + 1), root; id = sum = 0; memset(ball, -1, sizeof ball); memset(dp, -1, sizeof dp); parse(str, root, 1, len); solve(root, sum); if (dp[1][sum] == inf) puts("impossible"); else printf("%d\n", dp[1][sum]); } return 0; }
相关文章推荐
- UVALive - 4614 Moving to Nuremberg (树形DP)
- UVALive2038(树形dp)
- UVALive - 4015(树形DP)
- UVALive 4015 树形dp
- 【树形dp】UVALive 2038 Strategic game
- UVALive 2038 Strategic game--树形dp
- UVALive 2038 - Strategic game (经典树形DP)
- UVALive 4015 树形dp
- UVALive - 4614 Moving to Nuremberg (树形DP)
- UVALive 4015 Caves--树形dp
- UVALive - 4015 - 树形dp
- UVALive 5002 The Queue (树形Dp)
- UVaLive 10859 Placing Lampposts (树形DP)
- UVALive 3683 A Scheduling Problem(树形DP)
- uvalive 5088 hdu3066(树形dp)
- uvalive 4015 树形背包dp
- UVALive 4614 Moving to Nuremberg(树形DP)
- UVALive 6919 A game for kids(树形dp)
- UVALive 2038 Strategic game (树形DP,4级)
- UVALive - 5088 Alice and Bob's Trip 树形DP