NBUT动态规划专题——D - The more, The Better

Description

ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物。但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗? 
 

Input

每个测试实例首先包括2个整数,N,M.(1 <= M <= N <= 200);在接下来的N行里,每行包括2个整数,a,b. 在第 i 行,a 代表要攻克第 i 个城堡必须先攻克第 a 个城堡,如果 a = 0 则代表可以直接攻克第 i 个城堡。b 代表第 i 个城堡的宝物数量, b >= 0。当N = 0, M = 0输入结束。
 

Output

对于每个测试实例,输出一个整数,代表ACboy攻克M个城堡所获得的最多宝物的数量。
 

      本题是有依赖的背包问题,所有城堡的依赖关系可以形成森林,如果i依赖j,那么i称为附件,j称为主件,按照DD大牛《背包九讲》第6讲物品分组的思想(以下思想学自《背包九讲》),我们把主件和依赖于它的所有附件,看成一个物品组,但是,由于一个物品组的选择方案很多,假如有n个附件,那么方案数共有 2^n + 1,指数级别,但是,如果费用相同,我们显然是要选择价值最大的,也就是说这个物品组有很多方案是冗余的,完全可以忽略,按照这个思想,我们对主件的所有附件进行01背包,这样,我们就得到了费用为0 1 2 ......... V-c[i]的所有情况下的最大价值f,这里c[i]是主件的价值,至于为什么费用上限是V-c[i],因为取得附件,一定要取到主件,所有要为主件留下位置。我们可以把这些费用看成是"新物品"的费用,那么我们就得到了一个物品数是1+V-c[i]的物品组,例如费用是K+c[i],那么最大价值是f[k]+w[i]。还有注意,本题所有的依赖关系是森林,那么如果i是j的附件,也有可能i也是某个节点k的主件,唯一保证的是当前节点至多有1个主件,那么基本做法不变,只不过必须每次都要找到最底层,然后回溯上来,求得上一个节点的信息。

其他具体参见代码和注释。今天花了3小时来搞这个。。。。


//有依赖的背包问题

#include<stdio.h>
#include<string.h>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;

vector<int>tree[210];//存森林
int dp[210][210];// 考虑在以第i个节点为根的时候,攻击j个子节点所能获得的最大收益
int value[210];//攻击节点可以获得的价值
int n,m;
//对每个根下的节点进行01背包,排除冗余情况

void dfs(int rt,int v)//当前在rt节点 ,容量为v,那么每个物品组可以认为是一个泛化物品
{
int num=tree[rt].size();//当前rt节点的附件
dp[rt][1]=value[rt];// 只打一个的话,显然是主件
for(int i=0;i<num;i++)
{
if(v>1) //只有深搜到底,才可以回溯回来确定每个节点最优解
dfs(tree[rt][i],v-1);
for(int j=v;j>1;j--)//到底,进行01背包
{
for(int k=0;k<=j-1;k++)//体积变化,也就是攻击数目变化。(泛化),记得留1个位置 ,
dp[rt][j]=max(dp[rt][j],dp[rt][j-k]+dp[tree[rt][i]][k]);//攻击的这k个要由///子节点推出 ,这个状态方程的解释是这样的,要么不攻击,如果攻击,其价值是攻击rt节点下附属j-k个节点获得的最大价值+从rt的第i个节点攻击k个拿到的最大价值的和;
}
}
}


int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0 && m==0)
break;
int a,b;
memset(dp,0,sizeof(dp));
for(int i=0;i<=n;i++)
tree[i].clear();
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
tree[a].push_back(i);
value[i]=b;
}
dfs(0,m+1);//从虚拟节点0开始,那么位置(也就是容量)要+1
printf("%d\n",dp[0][m+1]);
}
return 0;
}


你可能感兴趣的:(NBUT动态规划专题——D - The more, The Better)