如题:http://poj.org/problem?id=2392
给出几种石头的每个的高度,使用当前石头不允许超过的最大高度,石头的数量,要求求所有石头最大能组成的高度。
首先由最大高度最小的那组拿石头,最后从最大高度最大的那组拿,保证了背包容量的不断增加,使得dp关系成立。
dp策略:当前最大高度是否可以达到,,这里使用了辅助数组used,used[i]代表了当前高度i之前使用当前种类石头的总数。通过记录使用石头数量保证对多重背包数量的限制。
dp的结果如果直接是最大高度是不可行的,背包的容量的变化会使dp多重背包混乱,结果不对。
特别要注意的,测试数据中会给出0,所以maxh初始为0,保证给出0输出0.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define Max(x,y)(x>y?x:y)
int f[40010];
int used[40010];
int K;
typedef struct Node
{
int c_w;
int num;
int v;
}node;
node a[405];
int maxh;
int cmp(node &a,node &b)
{
return a.v<b.v;
}
int main()
{
while(~scanf("%d",&K))
{
maxh=0;
memset(f,0,sizeof(f));
int i,j;
for(i=1;i<=K;i++)
scanf("%d%d%d",&a[i].c_w,&a[i].v,&a[i].num);
sort(a+1,a+1+K,cmp);
f[0]=1;
for(i=1;i<=K;i++)
{
memset(used,0,sizeof(used));
for(j=a[i].c_w;j<=a[i].v;j++)
if(!f[j]&&f[j-a[i].c_w]&&used[j-a[i].c_w]+1<=a[i].num)
{
f[j]=1;
used[j]=used[j-a[i].c_w]+1;
if(maxh<j)
maxh=j;
}
}
printf("%d\n",maxh);
}
return 0;
}