#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。此算法空间复杂度较低。