huynhduy.idol's blog

By huynhduy.idol, history, 7 years ago, In English

Hi codeforces, I'm trying to solve a dp on tree problem and it's hard for me. I need a help to find a right solution for it. plz help me... Problems decription: You have a tree with n nodes. Count the number of ways to delete some nodes such as the tree will be split into exactly k subtrees. (1 <= K, N <= 100). Sorry for my bad english... I really need a hint for that problems.

Tags dp, tree
  • Vote: I like it
  • +6
  • Vote: I do not like it

»
7 years ago, # |
Rev. 2   Vote: I like it +7 Vote: I do not like it

Hi huynhduy.idol, I will try my best to outline a solution. However, without a link I am unable to confirm that it is perfect, as I can't submit it to check.

Your DP state should be dp[type][node][numk] = ways to split the subtree of node, into numk different subtrees. "type" means that node has been deleted when you are counting. Now, the key idea is that at each node we update our DP from one child at a time. Therefore we are implicitly actually making our state dp[node][x][numk], meaning this is the value for node when we only take into account the first x children — but remember this is implicit (you don't have to code this part specifically).

Next, your recurrence should look like this.

for each node:
    dp[0][node][1] = 1 //we start with just the current node, as we haven't added any children to our dp yet. node hasn't been deleted
    dp[1][node][0] = 1 //we can also start with no node, if we delete this current one, so type=1
    for each number i < K (let i represent the number of subtrees which remain from dp[node]:
        for each number j < K (let j represent the number of subtrees which get created from child:
            dp[0][node][i+j-1] = dp[0][node][i] * dp[0][child][j] //we keep both node and child, resulting in one subtree overlap, as one gets merged with another
            dp[0][node][i+j] = dp[0][node][i] * dp[1][child][j] //the child is deleted so there is no overlap
            dp[1][node][i+j] = dp[1][node][i] * dp[0][child][j] //the node is deleted so there is no overlap
            dp[1][node][i+j] = dp[1][node][i] * dp[1][child][j] //both the node and the child are deleted, no overlap

answer: dp[0][root][K] + dp[1][root][K]

Be careful with overflow. Again, please give me a link so I can check this. Also, you can solve this in N^2 without too much difficulty by using a tree dp trick, where you only iterate i up to the current sum of subtree sizes (i in above code).

»
7 years ago, # |
  Vote: I like it +3 Vote: I do not like it

Can you please share the link of this problem?