UVa 12186 工人的請願書(樹形DP)
阿新 • • 發佈:2018-10-31
首先定義一下狀態dp[i]表示的是編號為i的人(不必區分是不是工人)向其上級傳送請願書所需要的工人數量的最小值,最後答案即是dp[0]。邊界條件:葉子節點即工人向上傳送請願書所需要的工人數量的最小值dp[]為1,狀態轉移:一個非葉子節點的dp[]由其所有的兒子節點裡前peo小的dp[]轉移而來。
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+10; int dp[maxn],n,req; vector<int>g[maxn]; void dfs(int now) { int sz=g[now].size(); if(sz==0) { dp[now]=1; returfa ; } for(int i=0;i<sz;i++) { int v=g[now][i]; dfs(v); } int peo=ceil(req*1.0/100*sz); vector<int>tmp; tmp.clear(); for(int i=0;i<sz;i++) tmp.push_back(dp[g[now][i]]); sort(tmp.begin(),tmp.end()); dp[now]=0; for(int i=0;i<peo;i++) { dp[now]+=tmp[i]; } } int main() { while(scanf("%d %d",&n,&req)!=EOF) { if(n==0&&req==0) break; for(int i=0;i<=n;i++) g[i].clear(); for(int i=1;i<=n;i++) { int u,v=i; scanf("%d",&u); g[u].push_back(v); } dfs(0); printf("%d\n",dp[0]); } return 0; }