np背包问题算法:折半枚举
Posted rstz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了np背包问题算法:折半枚举相关的知识,希望对你有一定的参考价值。
先看题吧
我猜到多数人开始想的就是二进制暴力枚举,对吧,这题这样做可以因为只需要提交答案,完全可以本地暴力,1e9的数据。需要一分钟左右。
代码:
这里我就不说着种方法了。
这题我们可以用,折半枚举。
优点:就是能够将时间复杂度降下来,将2^30 变为 2^15 + 2^15
解决这题仅仅用了不到1s的时间
代码也 相当于模板
1 #include <algorithm> 2 #include <map> 3 #include <string> 4 #include <iostream> 5 using namespace std; 6 typedef long long LL; 7 8 constexpr size_t maxn = 100; 9 10 LL A[100]; 11 map<LL, string> map1; 12 int main(){ 13 LL n; 14 LL value; 15 cin >> value >> n; 16 for(int i = 0; i < n; ++ i){ 17 cin >> A[i]; 18 } 19 for(int i = 0; i < (1 << (n/2)); ++ i){//将前半部分枚举 20 21 string a = ""; 22 LL sum = 0; 23 for(int j = 0; j < (n/2); ++ j){ 24 25 if(i&(1<<j)){ 26 sum += A[j]; 27 a = a + ‘1‘; 28 } 29 else 30 a = a + ‘0‘; 31 } 32 33 map1[sum] = a; 34 } 35 for(int i = 0; i < (1 << (n - n/2)); ++ i){//枚举后半部分 36 37 string a = ""; 38 LL sum = 0; 39 40 for(int j = 0; j < (n - n/2); ++ j){ 41 42 if(i&(1<<j)){ 43 sum += A[j + n/2]; 44 45 a = a + ‘1‘; 46 } 47 else 48 a = a + ‘0‘; 49 } 50 51 LL cd = value - sum; 52 53 auto iter = map1.find(cd);//查找 54 if(iter != map1.end()){//找到退出 55 cout << iter->second << a << endl; 56 return 0; 57 } 58 } 59 return 0; 60 }
以上是关于np背包问题算法:折半枚举的主要内容,如果未能解决你的问题,请参考以下文章