Gym - 101116K ——Mixing Bowls(树形dp)
2017-02-27 21:26
387 查看
原题:https://odzkskevi.qnssl.com/efe310c5868f7c1881a7cec2c6b3e9cc?v=1487513501
You are following a recipe to create your lunch.The recipe is a mixture made by combining ingredients togetherin a bowl. Each ingredient will be either:Another mixture which you must make rst in a separate bowl;or A basic ingredient you already have in
your kitchen, which canbe added directly. To make a mixture, you need to have all itsingredients ready, take an empty bowl and mix the ingredients init. It is not possible to make mixtures by adding ingredients to analready-existing mixture in a bowl.For example,
if you want to make CAKE (a mixture) out of CAKEMIX(a mixture) and lies (a basic ingredient), then you must rstmake CAKEMIX in its own bowl, then add the CAKEMIX and lies toa second bowl to make the CAKE.Once you have used a mixture as an ingredient and emptied
thebowl it was prepared in, you can re-use that bowl for anothermixture. So the number of bowls you need to prepare the recipewill depend on the order in which you decide to make mixtures.Determine the minimum number of bowls you will need.
其实想通的话就是一个简单的dfs。
首先可以通过复合物之间的关系建树。当你合成某一种复合物时,如果你需要使用x个碗,那么合成完以后,就会空出来x-1个碗,那么我当然希望,剩下需要的混合物的合成能利用这x-1个碗。所以我会选择先合成需要碗数量多的混合物,再用空出得碗去合成需要碗数量少得混合物。
对于每一个混合物,dfs出其原材料中每一种混合物需要的碗的数量,按其数量从大到小排序,第i个合成得混合物需要dp[i]个碗去合成这个混合物,还需要i-1个碗去装已经完成得混合物。所以就是i-1+dp[i]的最大值
另外如果原材料有y种混合物,那么你至少需要的碗得数量是y-1。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
const int MAXN=2010;
struct node{
int cnt;
int num;
int m;
string name;
string part[15];
};
node a[MAXN];
int cmp(int a,int b){
return a>b;
}
map <string,int> mp;
void dfs(int x){
if(a[x].cnt==0)
return;
int temp[15];
int tot=0;
for(int i=0;i<a[x].m;i++){
if(isupper(a[x].part[i][0])){
//cout<<"[[["<<a[x].part[i]<<" "<<mp[a[x].part[i]]<<endl;
dfs(mp[a[x].part[i]]);
temp[tot++]=a[mp[a[x].part[i]]].num;
}
}
sort(temp,temp+tot,cmp);
a[x].num=a[x].cnt+1;
for(int i=0;i<tot;i++){
a[x].num=max(a[x].num,temp[i]+i);
}
//cout<<a[x].name<<" "<<a[x].cnt<<" "<<a[x].num<<endl;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
cin>>a[i].name;
mp.insert(make_pair(a[i].name,i));
cin>>a[i].m;
a[i].cnt=0;
for(int j=0;j<a[i].m;j++){
cin>>a[i].part[j];
if(isupper(a[i].part[j][0]))
a[i].cnt++;
}
if(a[i].cnt==0)
a[i].num=1;
}
dfs(0);
printf("%d\n",a[0].num);
//system("pause");
}
You are following a recipe to create your lunch.The recipe is a mixture made by combining ingredients togetherin a bowl. Each ingredient will be either:Another mixture which you must make rst in a separate bowl;or A basic ingredient you already have in
your kitchen, which canbe added directly. To make a mixture, you need to have all itsingredients ready, take an empty bowl and mix the ingredients init. It is not possible to make mixtures by adding ingredients to analready-existing mixture in a bowl.For example,
if you want to make CAKE (a mixture) out of CAKEMIX(a mixture) and lies (a basic ingredient), then you must rstmake CAKEMIX in its own bowl, then add the CAKEMIX and lies toa second bowl to make the CAKE.Once you have used a mixture as an ingredient and emptied
thebowl it was prepared in, you can re-use that bowl for anothermixture. So the number of bowls you need to prepare the recipewill depend on the order in which you decide to make mixtures.Determine the minimum number of bowls you will need.
其实想通的话就是一个简单的dfs。
首先可以通过复合物之间的关系建树。当你合成某一种复合物时,如果你需要使用x个碗,那么合成完以后,就会空出来x-1个碗,那么我当然希望,剩下需要的混合物的合成能利用这x-1个碗。所以我会选择先合成需要碗数量多的混合物,再用空出得碗去合成需要碗数量少得混合物。
对于每一个混合物,dfs出其原材料中每一种混合物需要的碗的数量,按其数量从大到小排序,第i个合成得混合物需要dp[i]个碗去合成这个混合物,还需要i-1个碗去装已经完成得混合物。所以就是i-1+dp[i]的最大值
另外如果原材料有y种混合物,那么你至少需要的碗得数量是y-1。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
const int MAXN=2010;
struct node{
int cnt;
int num;
int m;
string name;
string part[15];
};
node a[MAXN];
int cmp(int a,int b){
return a>b;
}
map <string,int> mp;
void dfs(int x){
if(a[x].cnt==0)
return;
int temp[15];
int tot=0;
for(int i=0;i<a[x].m;i++){
if(isupper(a[x].part[i][0])){
//cout<<"[[["<<a[x].part[i]<<" "<<mp[a[x].part[i]]<<endl;
dfs(mp[a[x].part[i]]);
temp[tot++]=a[mp[a[x].part[i]]].num;
}
}
sort(temp,temp+tot,cmp);
a[x].num=a[x].cnt+1;
for(int i=0;i<tot;i++){
a[x].num=max(a[x].num,temp[i]+i);
}
//cout<<a[x].name<<" "<<a[x].cnt<<" "<<a[x].num<<endl;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
cin>>a[i].name;
mp.insert(make_pair(a[i].name,i));
cin>>a[i].m;
a[i].cnt=0;
for(int j=0;j<a[i].m;j++){
cin>>a[i].part[j];
if(isupper(a[i].part[j][0]))
a[i].cnt++;
}
if(a[i].cnt==0)
a[i].num=1;
}
dfs(0);
printf("%d\n",a[0].num);
//system("pause");
}
相关文章推荐
- [暴力 树形DP] Codeforces Gym 100553H NEERC14 H. Hidden Maze
- Gym 100962J Jimi Hendrix (树形DP)
- Codeforces Gym-101617G - Rainbow Roads [树形DP]
- Gym 100962J Jimi Hendrix (DFS + 树形dp)
- gym 100496 House of Representatives(树形dp)
- [树形DP 费用流手动增广] Codeforces Gym 101190 NEERC 16 M. Mole Tunnels
- 【 Gym 101116K 】Mixing Bowls(dfs)
- Codeforces Gym 100339B Diversion 树形DP + LCA
- hdoj Free DIY Tour 1224 (树形DP记录路径)
- Gym 100792H Hashing (DP)
- 树形DP
- 【BZOJ 4169】 4169: Lmc的游戏 (树形DP)
- HDU 1520 Anniversary party [树形DP]
- HDU 1520 Anniversary party(树形DP-最大独立集)
- cqoi2017,bzoj4813小Q的棋盘(树形dp或瞎搞)
- URAL 1039. Anniversary Party(树形DP)
- bzoj 4033: [HAOI2015]树上染色 树形dp
- 51 nod 1378 夹克老爷的愤怒 树形dp + 贪心
- Gym - 101174E Passwords AC自动机+额外的限制条件+状态压缩dp
- HDU 4661 Message Passing(树形DP)