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. AI 技术发展飞快,高校 AI 教师的知识储备能满足学生旺盛的求知欲吗?
  2. 阿里P8连肝一周整理出这份python自动化测试实战PDF
  3. Microsoft Office相关开发组件
  4. SQL JOIN --Merge Join
  5. php中html富文本编辑器,php + wangEditor 富文本编辑器的配置
  6. mysql有没有单机版?
  7. mybatis+spring mvc 完美整合方案 查询,保存,更新,删除自动生成
  8. 物联网专题--基于APP Inventor的BLE蓝牙4.0数据通信
  9. MyBatis自学(1):MyBatis概述
  10. OSI参考模型(1)
  11. Enterprise Library 1.0
  12. ArcGIS Server Image 扩展模块
  13. 免费微信公众号专用h5在线电影票API
  14. android 7 zip压缩文件,7-zip怎么把大文件压缩到最小
  15. c语言求闰年while,基础练习 闰年判断 c语言
  16. arcgis api 4.X 加载天地图3D
  17. 如何获取手机app的签名
  18. [BCE]光照传感器测量光照度-arduino程序
  19. 杰理之虚拟U盘升级【篇】
  20. 【BZOJ】1535: [POI2005]Sza-Template

热门文章

  1. [适合非python新手]selenium自动化测试 4-浏览器插件
  2. 2022年十一届认证杯(小美赛)C题思路资料
  3. 考研复试-自我介绍(中+英)
  4. @Autowired自动装配
  5. nodejs-硬连接符号连接
  6. CG 制作行业的云渲染这个行业发展如何?
  7. 西门子 SCL 语言 模拟量转换小例程
  8. Python学习,Day9(附加flush缓存连接)
  9. 四阶幻方c语言编程,C语言四阶完美幻方.doc
  10. python读取.mat文件,python将变量存为.mat文件详细介绍