您的位置:首页 > 其它

hdu 3033 I love sneakers!(分组背包)

2012-08-16 14:23 176 查看
http://acm.hdu.edu.cn/showproblem.php?pid=3033

(1)本题为分组背包问题,输入时将数据存入到结构体中:

struct node
{
int p[120], v[120], tot;
}brand[12];


(2)每组至少要取一个,处理方式不叫特殊,自然也是本题的关键。首先要初始化:

for(i=1;i<12;i++)
for(j=0;j<=m;j++)
dp[i][j]=-(1<<28);


即除了 i=0 以外,均是非法数据(注意,i=0 的一组千万不能赋负无穷)。

之后是核心的部分:

for(i=1;i<=k;i++)
for(j=0;j<brand[i].tot;j++)
for(l=m;l>=brand[i].p[j];l--)
{
dp[i][l]=max(dp[i][l], dp[i][l-brand[i].p[j]]+brand[i].v[j]);    // 规划1
dp[i][l]=max(dp[i][l], dp[i-1][l-brand[i].p[j]]+brand[i].v[j]);  // 规划2
}


对于每一层 i (i>0)均有,初始值都是非法的(负无穷),若只有规划1处理,仍为非法。而经过“规划2”处理,有一部分的dp[i][l]变成了合法数值,这就保证了处理过至少一次的均为合法。但注意到规划2最多只能装进每一组中的一个(注意循环 j 和循环 l 的相对位置),而规划1可以装入一组中的任意多个(请仔细体会),故规划1也是必须的。

具体代码:

View Code

#include<stdio.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
int n, m, k;
struct node { int p[120], v[120], tot; }brand[12];
int dp[12][11000];
int main()
{
int i, j, k, l;
int a, b, c;
while(scanf("%d%d%d", &n, &m, &k)!=EOF)
{
for(i=0;i<12;i++) brand[i].tot=0;
for(i=1;i<=n;i++)
{
scanf("%d%d%d", &a, &b, &c);
brand[a].p[brand[a].tot]=b;
brand[a].v[(brand[a].tot)++]=c;
}
for(i=1;i<12;i++) for(j=0;j<=m;j++) dp[i][j]=-(1<<28);
for(i=1;i<=k;i++)
{
for(j=0;j<brand[i].tot;j++)
for(l=m;l>=brand[i].p[j];l--)
{
dp[i][l]=max(dp[i][l], dp[i][l-brand[i].p[j]]+brand[i].v[j]);
dp[i][l]=max(dp[i][l], dp[i-1][l-brand[i].p[j]]+brand[i].v[j]);
}
}
if(dp[k][m]<0) printf("Impossible\n");
else printf("%d\n", dp[k][m]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: