Description

$n$枚硬币正面朝上摆成一排,给定$a[1],a[2],…,a[m]$,每次操作可以翻转连续$a[i]$个硬币.要求经过最少次数的操作,使得仅第$x[1],x[2],…,x[k]$枚硬币反面朝上,输出最少次数.

Input

第一行三个整数$n,k,m$.

第二行$k$个整数表示需要反面朝上的硬币位置,从$1$编号.

第三行$m$个整数表示$a[1],a[2],…,a[m]$.

Output

一个整数表示答案,若无解,则输出$-1$.

Sample Input

10 8 2

1 2 3 5 6 7 8 9

3 5

Sample Output

2

HINT

$1\;\leq\;n\;\leq\;10^4,1\;\leq\;k\;\leq\;10,1\;\leq\;m\;\leq\;100,1\;\leq\;a[i]\;\leq\;n$.

Solution

因为每次翻转改变的是相邻两个硬币之间的相对状态.

所以用$b[i]$表示相邻两个硬币之间的相对状态($0$:状态相同;$1$状态不同).

初始状态和终止状态便可知了,现在要将终止状态还原回初始状态.

每当翻转$[x+1,x+a[i]]$(长度为$a[i]$)时,只对$b[x],b[x+a[i]]$产生影响.

当$b[x]=b[x+a[i]]=0$时,操作劣.

当$b[x]=b[x+a[i]]=1$时,可消掉两个元素.

当$b[x]=0,b[x+a[i]]=1$时,相当于$x+a[i]$移动到$x$.

所以先预处理出每个$b[i]=1$的$i$到其他$b[j]=1$的$j$的距离$g[i][j]$,状压$dp$即可.

$f[i]$为到达状态$i$(二进制表状态)所需最少步数.

因为每个元素早消晚消都得消,而且顺序没影响,

所以设$k$为使得$i\&(1$<<$k)=1$最大的$k$,

则$f[i-(1$<<$j)-(1$<<$k)]=min(f[i]+g[j][k])(i\&(1$<<$j)=1,j\;\not=\;k)$.

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define K 25
#define M 105
#define N 10005
#define F 1048576
#define INF 20000000
using namespace std;
typedef long long ll;
int g[K][K],f[F],a[M],p[K],dis[N],n,m,k,cnt=-1;
bool b[N];
queue<int> q;
inline void bfs(int u){dis[u]=0;q.push(u);while(!q.empty()){u=q.front();q.pop();for(int i=1;i<=m;++i){if(u-a[i]>=0&&dis[u]+1<dis[u-a[i]]){dis[u-a[i]]=dis[u]+1;q.push(u-a[i]);}if(u+a[i]<=n&&dis[u]+1<dis[u+a[i]]){dis[u+a[i]]=dis[u]+1;q.push(u+a[i]);}}}
}
inline void Aireen(){scanf("%d%d%d",&n,&k,&m);for(int i=1,j;i<=k;++i){scanf("%d",&j);b[j]=true;}for(int i=1;i<=m;++i)scanf("%d",&a[i]);for(int i=0;i<=n;++i)if(b[i]!=b[i+1])p[++cnt]=i;for(int i=0;i<F;++i)f[i]=INF;for(int i=0;i<=cnt;++i)for(int j=i+1;j<=cnt;++j)g[i][j]=g[j][i]=INF;for(int i=0;i<=cnt;++i){for(int j=0;j<=n;++j)dis[j]=INF;bfs(p[i]);for(int j=0;j<=cnt;++j)g[j][i]=g[i][j]=min(g[i][j],dis[p[j]]);}f[(1<<cnt+1)-1]=0;for(int i=(1<<cnt+1)-1,k;i;--i){for(k=cnt;k>=0;--k)if(i&(1<<k)) break;for(int j=0;j<=cnt;++j)if((i&(1<<j))&&j!=k) f[i-(1<<j)-(1<<k)]=min(f[i-(1<<j)-(1<<k)],f[i]+g[j][k]);}if(f[0]<INF) printf("%d\n",f[0]);else puts("-1");
}
int main(){freopen("coin.in","r",stdin);freopen("coin.out","w",stdout);Aireen();fclose(stdin);fclose(stdout);return 0;
}

转载于:https://www.cnblogs.com/AireenYe/p/6230700.html

[日常训练]翻转硬币相关推荐

  1. codeforces日常训练 C. Cutting Out - 二分搜索答案

    codeforces日常训练 C. Cutting Out - 二分搜索答案 题干 You are given an array s consisting of n integers. You hav ...

  2. 试题 算法训练 翻转旋转变换

    试题 算法训练 翻转旋转变换 资源限制 内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s 问题描述 现在有一张n行m列的由" ...

  3. DTOJ2548 翻转硬币

    DTOJ2548 翻转硬币 题目 题目描述 输入格式 输出格式 样例 样例输入 样例输出 数据范围与提示 题解 题目 题目描述 nnn枚硬币正面朝上摆成一排,给定a1,a2,⋯,ama_1,a_2,\ ...

  4. 算法题 - 翻转硬币 - Python

    问题描述: 翻转硬币 小明的面前有一块长度为N的正方形棋盘,共有N*N个方格,在棋盘的每个格子上都放有一块硬币,要么正面朝上(以0表示),要么背面朝上(以1表示). 小明可以任意选择一列,将列上的硬币 ...

  5. 蓝桥杯矩阵翻转java_矩阵翻转硬币 蓝桥杯

    解题思路分析:           n=2, m=3 翻硬币过程(1代表正面,0代表反面): step 1 : step 2 : 当(x, y) = (1, 1)时, (i * x,  j * y)将 ...

  6. 「日常训练」Common Subexpression Elimination(UVa-12219)

    今天做的题目就是抱佛脚2333 懂的都懂. 这条题目干了好几天,最后还是参考别人的代码敲出来了,但是自己独立思考了两天多,还是有收获的. 思路分析 做这条题我是先按照之前的那条题目(The SetSt ...

  7. 「日常训练」 Mike and Fun (CFR305D2B)

    题意(CodeForces 548B) 每次对01矩阵中的一位取反,问每次操作后,单列中最长连续1的长度. 分析 非常非常简单,但是我当时训练的时候WA了四次...无力吐槽了,人间 不值得.jpg 代 ...

  8. 动规日常训练题解 难度普及+

    9.6 动规训练  题解 ----Frosty_Jackal 定义Dpmax[i][j] 表示l~r之间最大的得分,由题意得拆环为链,将1~n的枚举范围扩大到1~2*n ,外层枚举区间长,内层枚举l, ...

  9. 「日常训练」Bad Luck Island(Codeforces Round 301 Div.2 D)

    题意与分析(CodeForces 540D) 是一道概率dp题. 不过我没把它当dp做... 我就是凭着概率的直觉写的,还好这题不算难. 这题的重点在于考虑概率:他们喜相逢的概率是多少?考虑超几何分布 ...

最新文章

  1. 每日 30 秒 ⏱ 无障碍世界
  2. Intel Realsense 官方案例源码地址
  3. 【渝粤题库】陕西师范大学292071社会统计学作业(高起专)
  4. Linux 设备驱动的固件加载
  5. svn添加用户.sh
  6. 【从入门到放弃-Java】并发编程-NIO-Buffer
  7. win10安装python的xlrd_win10安装python的xlrd
  8. RabbitMQ + ELK 搭建日志平台
  9. php获取用户当前坐标,web端定位:获取当前地理位置
  10. JSON and Microsoft Technologies(翻译)
  11. 同一个事务里面对同一条数据做2次修改_MySQL事务与MVCC如何实现的隔离级别
  12. 在退出作用域时做一些事
  13. 三大代码审计工具对比
  14. 当机器学习遇上隐私保护,聊聊联邦学习和分布式机器学习
  15. 数据结构-六度空间(模拟六度分隔理论)
  16. EXCEL数组公式(2)---数组公式的基础概念等
  17. 看网易的lofter,预测轻博客的未来
  18. kubernetes之容器探针(liveness and readiness probe)
  19. CSharp(C#)语言_第一章
  20. 联想服务器td340安装精简版win10

热门文章

  1. 清空mailq 队列里面的邮件
  2. 小红书图集神器,轻松搞定收藏
  3. 【pig】pig的注释格式
  4. Oracle 统一审计(unified auditing)的概念
  5. LED全彩显示屏三种基色
  6. 一个女孩吃素5年后的大变化
  7. [Hadoop]ERROR security.UserGroupInformation:PriviledgedActionException as:Administrator
  8. Docker上配置Redis集群时出现No more cluster attempts left.
  9. 雷军的清华演讲-掌握你的运气
  10. Java虚拟机JVM简介与理解(一)