其他分享
首页 > 其他分享> > 2019牛客暑期多校训练营(第九场) - D - Knapsack Cryptosystem(折半枚举)

2019牛客暑期多校训练营(第九场) - D - Knapsack Cryptosystem(折半枚举)

作者:互联网

题目链接:https://ac.nowcoder.com/acm/contest/889/D

题意:挑选若干个数使得和为s。

思路:考虑二进制枚举,但是n的范围是36,直接枚举会超时,所以我们把数组分两部分枚举,然后用map映射一下即可。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll a[50], sum, s;
int m, n;
map <ll, string> mp1, mp2;
string str;
int main()
{
    scanf("%d%lld",&n, &s);
    for(int i = 0; i < n; i++) scanf("%lld", &a[i]);
    m = n / 2; n = n - m;
    for(int i = 0; i < (1 << m); i++)
    {
        sum = 0; str = "";
        for(int j = 0; j < m; j++)
        {
            if(i & (1 << j))
                sum += a[j], str += '1';
            else str += '0';
        }
        mp1[sum] = str;
    }
    for(int i = 0; i < (1 << n); i++)
    {
        sum = 0; str = "";
        for(int j = 0; j < n; j++)
        {
            if(i & (1 << j))
                sum += a[m+j], str += '1';
            else str += '0';
        }
        mp2[sum] = str;
    }
    for(auto it : mp1)
        if(mp2.count(s-it.first))
            return cout << it.second << mp2[s-it.first] << endl, 0;
}

 

标签:折半,map,int,scanf,Cryptosystem,多校,long,枚举,lld
来源: https://blog.csdn.net/sugarbliss/article/details/99683035