【题解】
题意:给定一个长度为n的序列,要求输出满足sum=s的序列元素的选择情况。
思路:要求sum=s,每个元素只能选择一次,第一反应是01背包,但是s有9*1e18,显然不可取,但是n最多只有36,因此我们可以利用这一点来枚举答案。2^36太大了,我们可以考虑折半枚举,这样的话最多是2^18+2^18,复杂度可行。
超大背包问题可以考虑折半枚举。
【代码】
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll m,a[40];
int n;
unordered_map <ll,int> mp;
int main()
{
scanf("%d%lld",&n,&m);
for(int i=0;i<n;i++) scanf("%lld",&a[i]);
int p1=n/2;
int p2=n-p1;
for(int i=1;i<(1<<p1);i++){
ll tp=0;
for(int j=0;j<p1;j++)
if(i&(1<<j)) tp+=a[j];
mp[tp]=i;
}
for(int i=1;i<(1<<p2);i++){
ll tp=0;
for(int j=p1;j<n;j++)
if