经过尝试,我把最短路写挂了。
但是,我过了这道题的双倍经验(那个 CF 题),十分搞笑,这题就过不了了。。。
/kel /kel 求调最短路
#include <bits/stdc++.h>
#define inf 100000007
#define rg register
using namespace std;
const int maxl=50005,maxk=17,maxp=70;
int read(){
int s=0,w=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') w=-w;ch=getchar();}
while (ch>='0'&&ch<='9'){s=s*10+(ch^'0');ch=getchar();}
return s*w;
}
int n,m,k,s,cnt;
int a[maxl],cf[maxl],x[maxl],l[maxl],d[maxk][maxk],f[(1<<maxk)+5];
int head[maxl],dis[maxl],vis[maxl];
struct edge{int nxt,to;}e[maxl*maxp*2];
void add_edge(int u,int v){
cnt++;
e[cnt].to=v,e[cnt].nxt=head[u],head[u]=cnt;
}
void SPFA(){
queue<int> q;
q.push(s),vis[s]=1,dis[s]=0;
while (!q.empty()){
int now=q.front();q.pop();
vis[now]=0;
for (int i=head[now];i;i=e[i].nxt){
int y=e[i].to;
if (dis[y]>dis[now]+1){
dis[y]=dis[now]+1;
if (!vis[y]) q.push(y),vis[y]=1;
}
}
}
}
signed main(){
n=read()+1,m=read(),k=read();
for (int i=1;i<=m;i++) x[i]=read(),a[x[i]]=1;
for (int i=1;i<=k;i++) l[i]=read();
for (int i=1;i<=n;i++) cf[i]=a[i]^a[i-1];
m=0;
for (int i=1;i<=n;i++){
if (cf[i]) x[++m]=i;
}
for (int i=1;i<=k;i++){
int len=l[i];
for (int j=1;j<=n-len;j++) add_edge(j,j+len),add_edge(j+len,j);
}
for (int i=1;i<=m;i++){
for (rg int j=1;j<=n;j++) dis[j]=inf,vis[j]=0;
s=x[i],SPFA();
for (int j=1;j<=m;j++) d[i][j]=dis[x[j]];
}
for (int i=0;i<(1<<m);i++) f[i]=inf;
f[(1<<m)-1]=0;
for (int i=(1<<m)-1;i>=1;i--){
int u;
for (int j=0;j<m;j++){
if (i&(1<<j)){u=j+1;break;}
}
for (int v=1;v<=m;v++){
if (u==v) continue;
if (!(i&(1<<(v-1)))) continue;
int p=i-(1<<(u-1))-(1<<(v-1));
f[p]=min(f[p],f[i]+d[u][v]);
}
}
if (f[0]==inf) cout<<-1<<endl;
else cout<<f[0]<<endl;
return 0;
}