11月16日

来源:互联网 发布:达芬奇 知乎 编辑:程序博客网 时间:2024/05/16 18:23
        这些天研究树形dp,首先看的是Anniversary party 这道题,也算是新手入门题,题意是给你一棵树,每个点都有权值,现在要你选一些点,这些点与父亲不能同时选,问权值最大多少。有两种情况1.dp[u][0]:表示u这个人不去,那么他的手下v可以选择去或者不去。dp[u][0]+=max(dp[v][0],dp[v][1]);  2.dp[i][1]:表示u这个人去, 那么由题意他的手下肯定不会去,dp[u][1]+=dp[v][0]。然后就是dfs这个关系树了。然后是apple tree这道题,题意是给你一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走V步,最多能遍历到的权值。用dp[root][k]表示以root为根的子树中最多走k时所能获得的最多苹果数,进行一次背包,就可以得出此时状态的最优解了,但是在进行背包的时候,对于某个孩子son走完之后是否回到根结点会对后面是否还能分配有影响,我们需要在状态中增加一维就,用dp[root][k][0]表示在子树root中最多走k步,最后还是回到root处的最大值,dp[root][k][1]表示在子树root中最多走k步,最后不回到root处的最大值。状态转移方程的步数也要好好想一想,dp[root][j][0] = max (dp[root][j][0] , dp[root][j-k][0] + dp[son][k-2][0]);//从s出发,要回到s,需要多走两步;dp[root][j]][1] = max(  dp[root][j][1] , dp[root][j-k][0] + dp[son][k-1][1]) ;//先遍历s的其他子树,回到s,遍历t子树,在当前子树t不返回,多走一步;dp[root][j][1] = max (dp[root][j][1] , dp[root][j-k][1] + dp[son][k-2][0]);//不回到s,在t子树返回,同样有多出两步。接着是 Starship Troopers 这道题,题目真长,题意是有 n个山洞,每个山洞中都有一些 bugs,每个山洞中都有一定的概率包含一个 brain。所有的山洞形成一棵树,现在给你 m个士兵,每个士兵都能消灭 20 个 bugs,并占领这个山洞,山洞的入口的编号是 1,问怎么安排士兵占领山洞才能使捕获 brain 的概率最大。用 f[u][P] 表示用 P 个士兵占领以 u 为根节点的子树所能获得的概率最大值,目标状态就是 f[1][m]。f[u][p] = max {f[u][p], f[u][p - k] + f[v][k] };其中v是u的子节点。也是明白vector<int> **[***]这个东西怎么用的了。
原创粉丝点击