原题:https://www.vijos.org/p/1133
时间:2014.3.22
类型:01背包
题解:初次学习这个,v为总容积,n为物品件数,a[i]为第i件物品的体积(费用),c[i]为第i件物品的价值
f[i][j]代表前i个物品恰好放入体积为j的背包中的总价值
那么 f[i][j]=max{ f[i-1][j],f[i-1][j-a[i]]+c[i] } 理由很简单,对于某个物品,可以有两种选择:拿或者不拿;
如果不拿,显然f[i][j]=f[i-1][j] ,拿的话就为f[i-1][j-a[i]]+c[i]
但是这个题目没有价值,怎么处理?经过skydec点拨,其实这题要求我们尽量多放,那么c[i]=a[i]
这里还可以优化,就是判断a[i]?<=j,如果为假,那么f[i][j]必定为f[i-1][j]
还要注意:此题不要心疼空间,数组开在main函数里并且向我一开始还用动态内存分配的话会RE的
源码:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int a[31],f[31][20001];
int max(int x,int y)
{
if(x>y) { return x; }
else { return y; }
}
int main()
{
int v,n;
scanf("%d",&v);
scanf("%d",&n);
for(int i=1;i<=n;i++) { scanf("%d",&a[i]); }
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
{
for(int j=v;j>=1;j--)
{
if(a[i]<=j)
{
f[i][j]=max(f[i-1][j],f[i-1][j-a[i]]+a[i]);
}
else { f[i][j]=f[i-1][j]; }
}
}
printf("%d",v-f[n][v]);
system("pause");
return 0;
}
最后状态:AC