1. 01揹包
hdoj 2602 Bone Collector
`#include <stdio.h>
int main(void)
{
int t,n,v,c[1000],w[1000],f[1000],i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&v);
for(i=0;i<n;i++)
{
scanf("%d",&w[i]);
}
for(i=0;i<n;i++)
{
scanf("%d",&c[i]);
}
for(i=0;i<n;i++)
{
for(j=v;j>=c[i];j--)
{
f[j]=f[j]>f[j-c[i]]+w[i]?f[j]:f[j-c[i]]+w[i];
}
}
printf("%d\n",f[v]);
}
return 0;
}
问题分解:当前最优解,要么包含第i种物品,要么不包含第i种物品
DP[i][j]表示前i个物品,揹包容量为j的最优值。
状态转移方程为:
DP[i][j] = max(DP[i-1][j],DP[i-1][j-v[i]] + w[i])
2. 完全揹包
正着写。
3. 多重揹包
hdoj 2191 ( 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 )
#include<stdio.h>
#include<string.h>
int main()
{
int a[100],b[100],c[100],x[100],m,n,i,j,k,t;
scanf("%d",&t);
while(t--)
{
memset(x,0,sizeof(x));
scanf("%d%d",&m,&n);
for(i=0;i<n;i++)
{
scanf("%d%d%d",&a[i],&b[i],&c[i]);
}
for(i=0;i<n;i++)
{
for(j=0;j<c[i];j++)
{
for(k=m;k>=a[i];k--)
{
x[k]=x[k]>(x[k-a[i]]+b[i])?x[k]:(x[k-a[i]]+b[i]);
}
}
}
printf("%d\n",x[m]);
}
return 0;
}