这题很劲啊
首先令b[i]=a[i]^a[i+1];
这样对a进行的区间操作即为对b的单点修改
目的变成了将b进行一些长度两端点的反转,使其全为0
考虑一个1,一个0,可以看做1移动到了0的位置,两个1呢,则可以看成撞到一起消去了
那么可以bfs处理出每两个1间的最短路,状压dp转移就好了
1 #include2 #include 3 #include 4 #include 5 #include 6 #define N 40050 7 using namespace std; 8 int n,K,m; 9 int a[N],b[N],c[N],f[20][20],g[1<<20];10 int pos[20],tot;11 int bit[20];12 int vis[N],dis[N];13 int q[N],head,tail;14 int main(){15 bit[0]=1;16 for(int i=1;i<=18;i++)bit[i]=bit[i-1]<<1;17 scanf("%d%d%d",&n,&K,&m);18 for(int i=1,x;i<=K;i++)scanf("%d",&x),a[x]=1;19 for(int i=0;i<=n;i++)b[i]=a[i]^a[i+1];20 for(int i=1;i<=m;i++)scanf("%d",&c[i]);21 for(int i=0;i<=n;i++)if(b[i])pos[++tot]=i;22 for(int i=1;i<=tot;i++){23 memset(vis,0,sizeof vis);24 memset(dis,0x3f,sizeof dis);25 head=tail=1;q[1]=pos[i];vis[pos[i]]=1;dis[pos[i]]=0;26 while(head<=tail){27 int x=q[head++];28 for(int i=1;i<=m;i++){29 if(x-c[i]>=0&&!vis[x-c[i]]){vis[x-c[i]]=1;dis[x-c[i]]=dis[x]+1;q[++tail]=x-c[i];}30 if(x+c[i]<=n&&!vis[x+c[i]]){vis[x+c[i]]=1;dis[x+c[i]]=dis[x]+1;q[++tail]=x+c[i];}31 }32 }33 for(int j=1;j<=tot;j++)f[i][j]=dis[pos[j]];34 }35 memset(g,0x3f,sizeof g);36 g[0]=0;37 for(int i=0;i