HDU 3033 I love sneakers! 分组背包+约束限制(每组至少取一个)。
2012-08-13 19:21
477 查看
注意至少取一个,仔细分析一下,此时光靠一个一维数组是不可以完成状态转移的,必须用二维数组或两个一维数组(滚动数组)。
建议多用二维数组,二维数组比较好理解,不容易出错,除非数据量太大,二维开不下。当然,如果对状态转移理解的比较深刻可以尝试着写成滚动数组。
先讲一讲二维数组的做法:
dp[i][j]表示进行到了第i组容量为j所装载的最大价值。
则dp[i][j]这个状态必须从dp[i-1][j-w[x]]+p[x](选了第1个第i组的物品),dp[i][j-w[x]]+p[x](已经选过第i组的物品,这次又选了第i组的物品),dp[i][j](不选这个物品);
所以状态转移方程为:
dp[i][j]=max(dp[i][j],max(dp[i][j-w[x]]+p[x],dp[i-1][j-w[x]]+p[x]));
二维数组版:
ViewCode
#include<stdio.h>
#include<string.h>
#include<algorithm>
usingnamespacestd;
#defineinf1<<29
intn,sum,m;
intdp[10003];
intz[101],w[101],p[101];
intmain()
{
inti,j,k;
while(~scanf("%d%d%d",&n,&sum,&m))
{
for(i=1;i<=n;i++)
scanf("%d%d%d",&z[i],&w[i],&p[i]);
intg1=0,g2=1;
for(i=0;i<=sum;i++)
dp[g1][i]=0;
for(k=1;k<=m;k++)
{
for(j=0;j<=sum;j++)
dp[g2][i]=-inf;
for(j=sum;j>=0;j--)
for(i=1;i<=n;i++)
if(z[i]==k)
{
if(w[i]<=j)
dp[g2][j]=max(dp[g2][j],max(dp[g2][j-w[i]]+p[i],dp[g1][j-w[i]]+p[i]));
}
g1=!g1;g2=!g2;
}
printf("%d\n",dp[g1][sum]);
}
return0;
}
相关文章推荐
- HDU 3033 I love sneakers! 分组背包+约束限制(每组至少取一个)。
- HDU 3033 I love sneakers! (分组背包 每组至少选一个)
- hdu 3033 I love sneakers! 分组背包之每组至少取一个
- HDU 3033 I love sneakers! 每组最至少取一个的分组背包
- hdu 3033 I love sneakers!(分组背包+每组至少选一个)
- hdu 3033 I love sneakers!(分组背包,每组至少取1个)
- hdu 3033 I love sneakers! (多组背包变形-----每组至少选一个)
- HDU-3033 I love sneakers! (多重背包 每组至少买一个)
- hdu 3033 I love sneakers!(分组背包,每组至少取一件)
- HDU 3033 I love sneakers!(分组背包/至少选一个)
- hdu 3033 I love sneakers! (多组中至少选一个的背包)
- hdu 3033 分组背包(每组至少选一个)
- HDU 3033 I love sneakers!(分组背包->每组至少取一个)
- hdu 3033 分组背包 每组至少选一个
- hdu 3033 分组背包 每组至少选一个
- 【分组背包每组至少一个】HDU 3033
- HDU 3033 I love sneakers!(DP 背包 每组最小取一个的背包)
- hdu3033 I love sneakers!(分组背包+每组至少一个)
- HDU 3033(I love sneakers!)分组背包变形
- HDU 3033 I love sneakers!(分组背包)