DP像猴子一样爬上了树……QwQ


 

◇ 算法概述

基于树的模型,由于树上没有环,满足DP的无后效性,可以充分发挥其强大统计以及计算答案的能力。

一般来说树形DP的状态定义有三种:偏简单的,dp[u]表示以u为根的子树的最优解/方案数;带选择性质的:dp[u][0/1],表示以u为根的子树中选择/不选择u的最优解/方案数;dp[u][i] 表示以u为根的子树中,u的状态为i的最优解/方案数(其实就是第二种定义的扩展)。

一般来说题目给的是一个树形图,那么我们只需要从图中一个存在的节点开始DP即可。注意向下DP时不要重复访问父节点。

由于树这种结构中,儿子与父亲的关系比较紧密,我们一般采用记忆化搜索,可以减免大量不合法的计算(只有儿子与父亲之间才能直接计算)。


 

◇ 经典选讲

(均出自《算法竞赛入门经典》-刘汝佳)

【UVa 12186】Another Crisis(工人的请愿书)

<题意>

某公司里有一个老板和n(n≤10 5 )个员工组成树状结构,除了老板之外每个员工都有唯一的直属上司。老板的编号为0,员工编号为1~n。工人们(即没有直接下属的员工)打算签署一项请愿书递给老板,但是不能跨级递,只能递给直属上司。当一个中级员工(不是工人的员工)的直属下属中不小于T%的人签字时,他也会签字并且递给他的直属上司。问:要让公司老板收到请愿书,至少需要多少个工人签字?

<解析>

这道题实质上是给定了一个以老板为根的有根树,于是我们DP的起点便是老板。定义状态为dp[u]为员工u签字最少需要多少个人签字。

对于工人u(没有直接下属),能够直接提供一个签字,即dp[u]=1,仅需要一人签字。对于其他非工人员工v,我们计算出他的每一个直属下属的dp值,存入cnt;再通过题目提供的百分数,算出要让他签字,他的直属下属员工最少有多少个需要签字,记为Maxi;那么要让v签字,最少要签字的人数为cnt中前Maxi个最小的值之和。

因为我们要使答案尽量小,取前Maxi个最小的值就可以达到目的。

(详见代码,如果有一些没懂的可以在邮箱里询问~)

<源代码>

 1 /*Lucky_Glass*/
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 const int MAXN=int(1e5);
 8 vector<int> lnk[MAXN+5];
 9 int n,m;
10 int dp[MAXN+5];
11 inline bool cmp(int A,int B){return dp[A]<dp[B];}
12 int DP(int u){
13     if(dp[u]) return dp[u];
14     if(lnk[u].size()==0) return dp[u]=1;
15     vector<int> cnt;
16     for(int i=0;i<(int)lnk[u].size();i++)
17         cnt.push_back(DP(lnk[u][i]));
18     sort(cnt.begin(),cnt.end());
19     int Maxi=lnk[u].size()*m/100+(lnk[u].size()*m%100? 1:0);
20     for(int i=0;i<Maxi;i++)
21         dp[u]+=cnt[i];
22     return dp[u];
23 }
24 int main(){
25     //freopen("in.txt","r",stdin);
26     while(~scanf("%d%d",&n,&m) && n && m)
27     {
28         memset(dp,0,sizeof dp);
29         memset(lnk,0,sizeof lnk);
30         for(int i=1,pre;i<=n;i++)
31             scanf("%d",&pre),lnk[pre].push_back(i);
32         printf("%d\n",DP(0));
33     }
34     return 0;
35 }
Another Crisis

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-10
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-27
  • 2021-11-19
  • 2022-12-23
相关资源
相似解决方案