#include<iostream>
#include<cstdio>
using namespace std;
int v[21],w[21];
int main()
{
int n,c;
scanf("%d%d",&n,&c);
for(int i=1;i<=n;i++) scanf("%d%d",&v[i],&w[i]);//输入
int m=1<<n;//2^n
int ans=0;
for(int i=0;i<m;i++){//枚举所有情况
int x=0,y=0;
for(int j=1;j<=n;j++){
bool flag=(i>>(j-1))%2;//取i的二进制第j位
if(flag) x+=v[j],y+=w[j];//x,y分别表示当前体积、价值
if(x>c){
y-=w[j];//
break;
}
}
if(x<=c) ans=max(ans,y);//取最大价值
}
printf("%d",ans);//输出
return 0;
}
数据范围:输入的数据均不超过20,经典的搜索。
众所周知,01背包的正解是DP。但是本题输入的数据不超过20,是否可以暴力求解呢?
回归01背包的本质,每件物品只有0(不取)和1(取)和两种可能。直接暴力枚举的时间复杂度是O(2^n),意味着1s以内可以得到结果。
为了提升运算速度,采用二进制。二进制下i的第j位为0表示不取第j件物品,否则表示取第j件物品。
32ms,440KB,AC。此算法空间复杂度较低。