zoukankan      html  css  js  c++  java
  • 0-1背包(OJ0161)新解

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

  • 相关阅读:
    Alpha冲刺Day5
    Alpha冲刺Day4
    Alpha冲刺Day3
    团队作业——随堂小测
    Alpha冲刺Day2
    Alpha冲刺Day1
    团队项目需求分析
    结对项目第二次作业
    Linux中exec命令相关
    .lib和.dll文件
  • 原文地址:https://www.cnblogs.com/dong-ji-yuan/p/9799349.html
Copyright © 2011-2022 走看看