您的位置:首页 > 其它

[HDU] 1561 The more, The Better 树形DP加01分组背包

2013-08-07 17:44 429 查看
题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1561

方法:

表面上看输入是一个森林的结构,其实可以用0节点作为父节点将森林中所有的树串起来作为一个树,然后开始DP,设F(P,x)是P为根的子树上选x个能获得的最大值的集合。

      {

      {0}; x==0

F(P,x) =

      {v+P的价值|v属于{F(s,x1)|s是p的直接子节点 && 0<=x1<min( (p为根? x+1:x),m) }跑一个以一个s作为分组的01分组背包形成的集合};0<x<=min(((p为根? m:m-1)), p那里最多选出多少)

      }

代码:

#include <iostream>
#include <queue>
#include<algorithm>
using namespace std;
int n,m;
struct Staff
{
int cost;
int value;
};
struct Adge
{
int vetex;
Adge* nextAdge;
};
struct Node
{
Adge* firstAdge;
bool isRoot;
int value;
Staff staff[201];
int StaffCount;
int maxChose;
};
Node nodes[201];
int myMax(int x,int y)
{
return x>=y? x:y;
}
void createAdge(int father,int son)
{
Adge* adge = (Adge*)(malloc(sizeof(Adge)));
adge->vetex = son;
if(nodes[father].firstAdge==NULL)
adge->nextAdge = NULL;
else
adge->nextAdge = nodes[father].firstAdge;
nodes[father].firstAdge = adge;
}
void DFSDP(int root)
{
Adge* adge = nodes[root].firstAdge;
int v,sonCount=0;
int innerDP[205];
memset(innerDP,0,sizeof(innerDP));
while(adge!=NULL)
{
v= adge->vetex;
DFSDP(v);
nodes[root].maxChose+=nodes[v].maxChose;
for(int i=m;i>=0;i--)
for(int j=1;j<=nodes[v].StaffCount;j++)
if(nodes[v].staff[j].cost<=i)
innerDP[i] = myMax(innerDP[i-nodes[v].staff[j].cost]+nodes[v].staff[j].value,innerDP[i]);
adge=adge->nextAdge;
sonCount++;
}
if(sonCount==0)
{
nodes[root].StaffCount++;
Staff st;
st.cost=1;
st.value=nodes[root].value;
nodes[root].staff[nodes[root].StaffCount]=st;
}
else
{
int base = root==0?1:0;
for(int i=0;i<m+base&&i<nodes[root].maxChose+base;i++)
{
nodes[root].StaffCount++;
Staff st;
st.cost=i+(1-base);
st.value=innerDP[i]+nodes[root].value*(1-base);
nodes[root].staff[nodes[root].StaffCount]=st;
}
}
}
void main()
{
Staff st;
st.cost=st.value = 0;
while(scanf("%d %d",&n,&m)&&!(n==0 && m==0))
{
for(int i=0;i<=200;i++)
{
nodes[i].isRoot= false;
nodes[i].firstAdge=NULL;
nodes[i].StaffCount=1;
nodes[i].staff[nodes[i].StaffCount] = st;
nodes[i].maxChose=1;
}
int father,value;
for(int i=1;i<=n;i++)
{
scanf("%d %d",&father,&value);
nodes[i].isRoot = father==0 ?true :false;
nodes[i].value = value;
createAdge(father,i);
}
DFSDP(0);
for(int i=0;i<=nodes[0].StaffCount;i++)
{
if(nodes[0].staff[i].cost==m)
{
cout<<nodes[0].staff[i].value<<endl;
break;
}
}
}
}


感想:实在不知道这个报告应该怎么描述,反正就是知道
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: