Optimal Cut (树形dp+记忆化)

A cut of a binary tree is a set of tree nodes such as for each possible path from the root node to any
leaf node, just one node in the cut belongs to the path. In a weighted binary tree, one can compute a
weighted cut, because it would include weighted nodes. The total weight of such cut can be computed
by adding up the weights of the nodes in it. The figure below shows a weighted binary tree. The gray
nodes represent a weighted cut, and its total weight is 14.
Now, given a weighted binary tree, you have to write a program that finds the weighted cut with
the maximal total weight value among all possible weighted cuts in the tree. This is hereafter called
the Optimal Cut of the input binary tree. However, to make it a bit more interesting, your program
must find the optimal cut that includes no more than K nodes, and report its weight. In the figure
above, for instance, the nodes of the optimal cut sums 28 when K = 3, and 15 when K = 2.
Input
The input can contain several problems. Each problem contains the description of a complete binary
tree in a single line. This description corresponds to sequence of integer numbers, separated of each
other by a blank space. The description starts with an integer 0 ≤ H < 20 representing the height of
the tree, followed by another integer 1 ≤ K ≤ 20 representing the maximum number of nodes in the
optimal cut to be found. Then, the weights −103 ≤ W i ≤ 103 of the nodes follow, listed in pre-order.
The end of input is indicated by a single line containing only an integer value of ‘-1’.
Output
For each problem in the input, the output should be a single line with a single integer number, representing
the total weight of the optimal cut found.
Sample Input
2 3 8 6 7 -2 -1 2 1
0 1 1
3 3 -8 1 0 0 1 2 1 1 -1 1 1 1 3 1 4
-1
Sample Output
9
1

5

题目大概:

给出一颗满二叉树,然后给出k,要求找出最大的k个切割点,使得切割点的价值之和最大。

切割点 就是把这棵树的切割点去掉,从这棵树的根不能到达任何叶子节点。

思路:

在给个结点都建立一个数组保存,一给节点为根的子树的最大j切割点的值,j(1--k)。

用dfs遍历一遍,最终用子节点更新父节点,根节点的最大的k切割点就会求出。

代码:

#include <bits/stdc++.h>

using namespace std;
const int maxn=(1<<20)+10;
int dp[maxn][23],vis[maxn][23];
int a[maxn];
int h;
//
void build(int rt,int x)
{
    if(x>h)return;
    scanf("%d",&a[rt]);
    build(rt*2,x+1);
    build(rt*2+1,x+1);
}
void dfs(int rt,int k,int x)
{
    if(vis[rt][k])return;
    vis[rt][k]=1;
    dp[rt][k]=a[rt];
    if(x+1>h)return;
    for(int i=1;i<k;i++)
    {
        dfs(rt*2,i,x+1);
        dfs(rt*2+1,k-i,x+1);
        dp[rt][k]=max(dp[rt][k],dp[rt*2][i]+dp[rt*2+1][k-i]);
    }

}
int main()
{
    int k;
    while(scanf("%d",&h)&&(h!=-1))
    {
        memset(vis,0,sizeof(vis));
        scanf("%d",&k);
        build(1,0);
        dfs(1,k,0);
        printf("%d\n",dp[1][k]);
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/a1046765624/article/details/80662046
cut
今日推荐