您的位置:首页 > 其它

初涉分组背包 HDU 1561 The more,The better

2014-04-30 14:01 363 查看
给出一个森林,每棵树均为一组物品,首先推出每棵树可以组成的物品种类。

然后是基本的分组背包模板。

即 最外层枚举组数,次外层枚举背包容量,内层枚举物品体积。

 对于每棵树有 ans[root][i+j] = ans[root][ i ] + ans[son][ j ]。

 题水数据也水,不多说了。

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <stack>
#include <map>

#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long int
#define _LL __int64
#define _INF 0x3f3f3f3f
#define Mod 1000000007
#define LM(a,b) (((ULL)(a))<<(b))
#define RM(a,b) (((ULL)(a))>>(b))

using namespace std;

const int MAXN = 210;

struct N
{
int u,v,w,next;
} edge[MAXN*2];

int head[MAXN];

int Top;

void Link(int u,int v,int w = -1)
{
edge[Top].u = u;
edge[Top].v = v;
edge[Top].w = w;
edge[Top].next = head[u];
head[u] = Top++;
}

void Init_head_Top(int n)
{
memset(head,-1,sizeof(int)*(n+2));
Top = 0;
}

int dp[MAXN];

int ans[MAXN][MAXN];

int root[MAXN];

int Top_Root;

int price[MAXN];

void dfs(int s,int m)
{
ans[s][1] = price[s];

for(int p = head[s] ; p != -1; p = edge[p].next)
{
dfs(edge[p].v,m);

for(int i = m;i >= 0; --i)
{
for(int j = m-i;j >= 1; --j)
{
if(ans[s][i] != -1 && ans[s][i+j] < ans[s][i] + ans[edge[p].v][j])
ans[s][i+j] = ans[s][i] + ans[edge[p].v][j];
}
}

}
}

int main()
{
int n,m;

int i,j,k,v;

while(scanf("%d %d",&n,&m) && (n||m))
{
Init_head_Top(n);

Top_Root = 0;

memset(dp,-1,sizeof(dp));
memset(ans,-1,sizeof(ans));

for(i = 1; i <= n; ++i)
{
scanf("%d %d",&v,&price[i]);
if(v)
Link(v,i);
else
root[Top_Root++] = i;
}

for(i = 0; i < Top_Root; ++i)
{
dfs(root[i],m);
}

dp[0] = 0;

for(j = 0; j < Top_Root; ++j)
{
for(i = m;i >= 0; --i)
{
if(dp[i] != -1)
{
for(k = m-i;k >= 1; --k)
{
if(ans[root[j]][k] != -1 && dp[i] != -1 && dp[i+k] < dp[i] + ans[root[j]][k])
dp[i+k] = dp[i] + ans[root[j]][k];
}
}
}
}

// for(i = 1; i <= m; ++i)
// {
// // printf("cost = %2d w = %2d\n",i,dp[i]);
// }
//
// for(i = 1; i <= n; ++i)
// {
// for(j = 1; j <= m; ++j)
// {
// //printf("%2d ",ans[i][j]);
//
// }
// // puts("");
// }

int Max = dp[1];

for(i = 1; i <= m ; ++i)
Max = max(Max,dp[i]);
printf("%d\n",Max);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: