动态规划特训:工人的请愿书(UVA12186)

解题思路:对于每一位上司(代号u),可知其有k个直属下属,当人数达c=(k*T-1)/100+1时会申请,可以递归先求出其所有下属各自的达到申报需要的人数,然后排列选出前c个,即为最少需要的工人数。

题目大意:某公司有一老板(代号0),有直属下属,每一个直属下属也会有下属,最底下为工人,工人们的直属上司会在工人申请数达到百分之T时向上申请,问至少多少个工人申请才能送达给老板。

Sample Input

3 100

0 0 0

3 50

0 0 0

14 60

0 0 1 1 2 2 2 5 7 5 7 5 7 5

0 0

Sample Output

3 2 5

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;

int n,T;
vector<int> Q[100000];

int dfs(int u)
{
	vector<int> A;
	int ans;
	if(Q[u].empty()) return 1;   //如果为空表示到了叶子节点,返回1 
	for(int i=0;i<Q[u].size();i++)
	{
		A.push_back(dfs(Q[u][i]));
	}
	sort(A.begin(),A.end());
	int k=Q[u].size();
	int c=(k*T-1)/100+1;      //往大的方向加一使用的技巧,记住! 
	for(int i=0;i<c;i++)
	{
		ans+=A[i];
	}
	return ans;
}

int main()
{
	while(cin>>n>>T)
	{
		if(n==0&&T==0) break; 
		for(int i=0;i<=n;i++) Q[i].clear();  //记得清空 
		for(int i=1;i<=n;i++)    //利用vector一一对应9 
		{
			int tmp;cin>>tmp;
			Q[tmp].push_back(i);
		}
		cout<<dfs(0)<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/mavises/article/details/82191972