好久没写博客了,这段时间感觉比较懒了,今天一时兴起想写一下博客,做个题吧。。
题意:给你n个物品,重量分别为a[i],再给你m个砝码,让你称重,是否能把这n个物品都能称出来
(1)如果能 ,输出0
(2)如果不能,那找一个任意重量的砝码,看是否能称出来,如果能称出来那就输出这个砝码的重量,如果有多个答案,输出最小的那个;
(3)如果加一个砝码不能满足,输出-1。
思路:才开始的时候我用set存所有砝码任意组合的情况,然后遍历n个物品,复杂度为n*pow(3,m) ,果断超时,并且各种爆内存
比赛时各种自闭,嘤嘤嘤。后来才想到枚举各种情况时可以缩小砝码的范围,就是到第i个时,取1~(i-1)的交集,然后与第i个比较,再取交集,一直取到n,set中的第一个元素就是答案。。。
//#pragma GCC optimize (2)
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<math.h>
#include<time.h>
#include<vector>
#include<set>
#include<map>
#include <assert.h>
#include<stack>
#define LL long long
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const LL mod=1e9+7;
const double PI=acos(-1.0);
const LL INF=1e18;
const double eps=1e-10;
void quickread(){std::ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);}
int lowbit(int x){return x&(-x);}
int f[100005];
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
int gcd (int a,int b){return b==0?a:gcd(b,a%b);}
int a[120];
int b[120];
int ans;
int cnt=0;
set<int>vis;
set<int>vis2;
int n,m;
int vis3[120];
void dfs(int x,int sum)
{
if(x>=m+1)
{
int absum=abs(sum);
if(vis.find(absum)==vis.end())
vis.insert(absum);
return ;
}
dfs(x+1,sum);
dfs(x+1,sum-b[x]);
dfs(x+1,sum+b[x]);
return ;
}
int main()
{
while(~scanf("%d%d",&n,&m)&&n&&m)
{
vis.clear();
cnt=0;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int j=1;j<=m;j++) scanf("%d",&b[j]);
dfs(1,0);
int n1=n;
mem(vis3,0);
for(int i=1;i<=n;i++)
{
if(vis.find(a[i])!=vis.end())
vis3[i]=1,n1--;
}
if(n1==0)
{
printf("0\n");
continue;
}
vis2.clear();
int cnt=0;
for(int j=1;j<=n;j++)
{
if(vis3[j]) continue;
cnt++;
set<int>vis4;
if(cnt==1)
{
vis4.clear();
for(auto it=vis.begin();it!=vis.end();it++)
{
int x=abs(a[j]-*it);
int y=abs(a[j]+*it);
if(vis4.find(x)==vis4.end())
{
vis4.insert(x);
}
if(vis4.find(y)==vis4.end())
{
vis4.insert(y);
}
}
vis2.clear();
vis2=vis4;
continue;
}
for(auto it=vis2.begin();it!=vis2.end();it++)
{
int x=abs(a[j]-*it);
int y=abs(a[j]+*it);
if(vis4.find(x)==vis4.end()&&vis.find(x)!=vis.end())
{
vis4.insert(*it);
}
if(vis4.find(y)==vis4.end()&&vis.find(y)!=vis.end())
{
vis4.insert(*it);
}
}
vis2.clear();
vis2=vis4;
}
if(!vis2.empty()) printf("%d\n",*vis2.begin());
else printf("-1\n");
}
return 0;
}