k很小，先不管

01取反，等价于1走到0,11取反，等价于两个1消掉。

1一共只有20个

BFS求最短路

O(20*2^20)

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}
template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
namespace Modulo{
const int mod=998244353;
int mul(int x,int y){return (ll)x*y%mod;}
void inc2(int &x,int y){x=mul(x,y);}
int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}
}
//using namespace Modulo;
namespace Miracle{
const int N=10000+5;
const int M=105;
const int K=22;
const int inf=0x3f3f3f3f;
int n,k,m;
int pos[K],dis[N],cnt;
int f[K][K];
int a[N],b[N];
int dp[(1<<20)+23];
int q[N],l,r;
void bfs(int st){
memset(dis,0x3f,sizeof dis);
dis[pos[st]]=0;
l=1,r=0;
q[++r]=pos[st];
while(l<=r){
int x=q[l++];
for(reg i=1;i<=m;++i){
int to=x+b[i];
if(to<=n+1&&dis[to]>dis[x]+1){
dis[to]=dis[x]+1;
q[++r]=to;
}
to=x-b[i];
if(to>0&&dis[to]>dis[x]+1){
dis[to]=dis[x]+1;
q[++r]=to;
}
}
}
for(reg i=1;i<=cnt;++i){
f[st][i]=dis[pos[i]];
}
}
int num(int p){
int sz=__builtin_ctz(p);
return sz+1;
}
int main(){
rd(n);rd(k);rd(m);
for(reg i=1;i<=k;++i){
int x;rd(x);
a[x]=1;
}
for(reg i=1;i<=m;++i){
rd(b[i]);
}
for(reg i=n+1;i>=1;--i){
a[i]^=a[i-1];
if(a[i]==1) pos[++cnt]=i;
}
// prt(a,1,n+1);
// prt(pos,1,cnt);
for(reg i=1;i<=cnt;++i){
// cout<<" bfs i------------ "<<i<<endl;
bfs(i);
// prt(f[i],1,cnt);
}
memset(dp,0x3f,sizeof dp);
dp[0]=0;
for(reg s=1;s<(1<<cnt);++s){
int sz=__builtin_popcount(s);
if((sz&1)) continue;
// cout<<" ss "<<s<<endl;
int t=s&(-s);
for(reg tmp=s^t,p=tmp&(-tmp);tmp;tmp=tmp^p,p=tmp&(-tmp)){
// cout<<" t "<<t<<" num(t) "<<num(t)<<" p "<<p<<" num(p) "<<num(p)<<" fan "<<dp[s^t^p]<<endl;
dp[s]=min(dp[s],dp[s^t^p]+f[num(t)][num(p)]);
}
}
// prt(dp,0,(1<<cnt)-1);
if(dp[(1<<cnt)-1]==inf){
puts("-1");
}else{
printf("%d\n",dp[(1<<cnt)-1]);
}
return 0;
}

}
signed main(){
Miracle::main();
return 0;
}

/*
Author: *Miracle*
*/

posted @ 2019-05-27 20:55  *Miracle*  阅读(258)  评论(0编辑  收藏  举报