2019牛客暑期多校训练营(第九场)D.Knapsack Cryptosystem
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019牛客暑期多校训练营(第九场)D.Knapsack Cryptosystem相关的知识,希望对你有一定的参考价值。
链接:https://ac.nowcoder.com/acm/contest/889/D
题目描述
Amy asks Mr. B problem D. Please help Mr. B to solve the following problem.
Amy wants to crack Merkle–Hellman knapsack cryptosystem. Please help it.
Given an array ai with length n, and the sum s.
Please find a subset of ai, such that the sum of the subset is s.
For more details about Merkle–Hellman knapsack cryptosystem Please read
https://en.wikipedia.org/wiki/Merkle%E2%80%93Hellman_knapsack_cryptosystem
https://blog.nowcoder.net/n/66ec16042de7421ea87619a72683f807
Because of some reason, you might not be able to open Wikipedia.
Whether you read it or not, this problem is solvable.
输入描述:
The first line contains two integers, which are n(1 <= n <= 36) and s(0 <= s < 9 * 1018)
The second line contains n integers, which are ai(0 < ai < 2 * 1017).
ai is generated like in the Merkle–Hellman knapsack cryptosystem, so there exists a solution and the solution is unique.
Also, according to the algorithm, for any subset sum s, if there exists a solution, then the solution is unique.
输出描述:
Output a 01 sequence.If the i-th digit is 1, then ai is in the subset.
If the i-th digit is 0, then ai is not in the subset.
题意:
n个数,一个K,问你这n个数中哪几个数的加和是n,并用1标注出来?
思路:
折半搜索
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int n;
LL k,ans;
LL a[100];
int vis[100];
map<LL,LL>mp;
void dfs1(int pos,int en,LL sta,LL sum)
if(pos==en+1)
if(sum==k)
ans=sta;
return;
if(mp[sum]==0)
mp[sum]=sta;
// cout<<sum<<" "<<sta<<endl;
return;
if(sum==k)
ans=sta;
return;
if(mp[sum]==0)
mp[sum]=sta;
// cout<<sum<<" "<<sta<<endl;
//cout<<sum<<" "<<sta<<endl;
dfs1(pos+1,en,sta,sum);
dfs1(pos+1,en,sta|(1LL<<pos),sum+a[pos]);
void dfs2(int pos,int en,LL sta,LL sum)
if(pos==en+1)
if(sum==k)
ans=sta;
return ;
if(mp[k-sum]!=0)
ans=mp[k-sum]+sta;
return ;
if(sum==k)
ans=sta;
return ;
if(mp[k-sum]!=0)
ans=mp[k-sum]+sta;
dfs2(pos+1,en,sta,sum);
dfs2(pos+1,en,sta|(1LL<<pos),sum+a[pos]);
int main()
scanf("%d%lld",&n,&k);
for(int i=1; i<=n; i++)
scanf("%lld",&a[i]);
ans=0;
int mid=(n+1)/2;
if(ans==0)
dfs1(1,mid,0,0);
if(ans==0)
dfs2(mid+1,n,0,0);
for(int i=1; i<=n; i++)
if((ans>>i)&1)
printf("1");
else
printf("0");
return 0;
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
using namespace std;
const int N=40;
map<ll ,ll >mp;
ll index[N],a[N],target;
int n,mid;
ll ans;
void init()
index[1]=1;
for(int i=2;i<=N;i++)
index[i]=index[i-1]*2;
void DFS(int pos,ll sta,ll sum,int en)
if(pos==en+1)
if(pos==mid)
if(sum==target)
ans=sta;
mp[sum]=sta;;
else
if(mp[target-sum]!=0)
ans=sta+mp[target-sum];
return ;
DFS(pos+1,sta,sum,en);
DFS(pos+1,sta+index[pos],sum+a[pos],en);
int main()
init();
scanf("%d%lld",&n,&target);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
mid=n/2+1;
ans=0;
if(target) DFS(1,0,0,n/2);
if(!ans) DFS(n/2+1,0,0,n);
for(int i=1;i<=n;i++)
if(ans&1)
cout<<"1";
else
cout<<"0";
ans>>=1;
cout<<endl;
return 0;
以上是关于2019牛客暑期多校训练营(第九场)D.Knapsack Cryptosystem的主要内容,如果未能解决你的问题,请参考以下文章