Gym 101116K Mixing Bowls

来源:互联网 发布:ios ipv6网络问题 编辑:程序博客网 时间:2024/04/29 21:04

Gym 101116K Mixing Bowls

搜索 dfs 树形dp

传送门:CodeForces

传送门:HustOJ


题意

给定一个菜谱,大写的单词代表混合物,小写的代表基础原料。每个混合物由其它混合物或基础原料组成,不会间接或直接地需要自己。制备每个混合物必须先制备组成它的混合物。且混合物都要用一个碗装,当它作为原料去合成其它混合物后,碗就空出来了。求合成第一个混合物最少需要用几个碗。


思路

赛后想想,其实就是个深搜。

不过注意回溯时,比如0号食物有4个混合物组成(非混合物没用不考虑),他们的制备顺序是有关系的,因为制备后面的混合物时需要碗装前面的混合物。所以回溯时将0号食物原料中混合物需要的碗排序,从大到小。依次加上前面的碗的数目。

假设合成一个混合物需要dfs(i)个碗。
因为最后需要合成第一个混合物,所以我们以它为根进行dfs。
假设当前混合物的原料里有t个混合物,其中第j个合成的混合物需要need[j]个碗,且还要j-1个碗装前面j-1个混合物,因此此时需要j-1+need[j]个碗。
因此我们把need按从大到小排序,求出合成子混合物时所需的最大碗数,最后混合成当前混合物需要t+1个碗,取两者最大值即可。


代码

#include <cstdio>#include <cstdlib>#include <iostream>#include <algorithm>#include <string>#include <cstring>#include <vector>#include <cmath>#include <queue>#include <stack>#include <map>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define _ ios_base::sync_with_stdio(0);cin.tie(0);#define M(a,b) memset(a,b,sizeof(a))using namespace std;const int MAXN=1005;const int oo=0x3f3f3f3f;typedef __int64 LL;const LL loo=4223372036854775807ll;typedef long double LB;const LL mod=1e9+7;map<string, int> mp;struct Food{    int num;    int bow;    string name;    vector<string> f;    Food() { num=bow=0;name="";f.clear(); }}food[MAXN];int dfs(int n){    if(food[n].f.size()==0) return 1;    int tt[15]={0};    int am=food[n].f.size();    for(int i=0;i<am;i++)    {        tt[i]=dfs(mp[food[n].f[i]]);    }    sort(tt, tt+am);    food[n].bow=am+1;    for(int i=0;i<am;i++)    {        int temp=am-i-1;        food[n].bow=max(food[n].bow, tt[i]+temp);    }    return food[n].bow;}int main(){    _    int n;    while(cin>>n)    {        for(int i=0;i<n;i++)        {            cin>>food[i].name;            mp[food[i].name]=i;            int m;cin>>m;            for(int j=0;j<m;j++)            {                string temp;cin>>temp;                if(isupper(temp[0])) food[i].f.push_back(temp);            }        }        cout<<dfs(0)<<endl;    }    return 0;}
0 0
原创粉丝点击