[中等] UVa OJ 12186 Another Crisis

来源:互联网 发布:网络高级工程师认证 编辑:程序博客网 时间:2024/06/05 19:08

题目描述

基本思路:某种程度上我觉得这个题不应该算动态规划了,因为本身也没有重复求解的结点,而且也不是啥状态转移,我觉得应该算一个关于树的问题。

关于树的问题大部分都可以递归求解,本题也是。设让员工i签字并且向上递送所需要的工人签字数为d[i],则d[i]=sum{d[j],d[k],d[l],...},其中d[j],d[k],d[l]...为把i的直接下属的d值从小到大排序后前c个,其中c=(kT-1)/100+1,也就是%T的直接员工数。

具体代码:

#include <iostream>#include <algorithm>#include <vector>using namespace std;const int maxn=100000+5;vector<int> son[maxn];int d[maxn];int N,T;int dp(int b){    if(son[b].empty())        return d[b]=1;    if(d[b]>0)        return d[b];    vector<int> dson;    int k=son[b].size();    for(int i=0;i<k;++i)    {        dson.push_back(dp(son[b][i]));    }    sort(dson.begin(),dson.end());    int n=(k*T-1)/100+1;    int sum=0;    for(int i=0;i<n;++i)        sum+=dson[i];    return sum;}int main(){   // freopen("input.txt","r",stdin);    for(cin>>N>>T;N!=0||T!=0;cin>>N>>T)    {        fill(d,d+N+2,0);        for(int i=0;i<=N;++i)            son[i].clear();        for(int i=1;i<=N;++i)        {            int t;            cin>>t;            son[t].push_back(i);        }        cout<<dp(0)<<endl;    }    return 0;}


原创粉丝点击