0
点赞
收藏
分享

微信扫一扫

2019牛客暑期多校训练营(第九场)D.Knapsack Cryptosystem

炽凤亮尧 2023-02-07 阅读 101


链接: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;
}

 

举报

相关推荐

0 条评论