CF79D Password
题意:给定长度为n的0/1序列,初始值都为0。你每次可以在给定的l个长度中的\(a_i\)并将序列中长度为\(a_i\)的部分取反。使得最终状态为\(x_1\)~\(x_k\),求最少取反次数。
分析:看到这种区间整体变化的题,我们应该直觉想到差分(也可能想到线段树
先求出差分后的数组,然后每次操作相当于对距离为\(a_i\)的两点取反。
我们可以用类似求最短路的方法求出取反i,j位的最小操作次数。
因为最后为1的位置 \(\leq\) 10,所以操作的次数 \(\leq\) 20。
所以就可以大力状压了,方程见代码。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int dp[1<<20], num[1<<20], low[1<<20], f[10005], dis[10005], mn[22][22], len[105], cnt[22];
int n, k, l, tot=0;
queue<int> q;
inline int read()
{
int x=0,f=1; char ch=getchar();
for (; ch<'0' || ch>'9'; ch=getchar()) if (ch=='-') f=-1;
for (; ch>='0' && ch<='9'; ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
void Get_Shortest_Path(int rt)
{
memset(dis, 0x3f, sizeof(dis)); dis[cnt[rt]]=0;
q.push(cnt[rt]);
while (!q.empty())
{
int u=q.front(); q.pop();
for (int i=1; i<=l; i++)
{
if (u+len[i]<=n+1 && dis[u+len[i]]>dis[u]+1)
{dis[u+len[i]]=dis[u]+1; q.push(u+len[i]);}
if (u-len[i]>0 && dis[u-len[i]]>dis[u]+1)
{dis[u-len[i]]=dis[u]+1; q.push(u-len[i]);}
}
}
for (int i=1; i<=tot; i++) mn[rt][i]=dis[cnt[i]];
}
int main()
{
n=read(); k=read(); l=read();
for (int i=1; i<=k; i++) {int x=read(); f[x]=1;}
for (int i=1; i<=n+1; i++) if (f[i]^f[i-1]) cnt[++tot]=i;//差分
for (int i=1; i<=l; i++) len[i]=read();
for (int i=1; i<=tot; i++) Get_Shortest_Path(i);//预处理取反i,j位的最小操作次数
low[1]=0; for (int i=2; i<(1<<tot); i++) low[i]=low[i>>1]+1;//预处理log_2
for (int i=1; i<(1<<tot); i++) num[i]=num[i-(i&-i)]+1;//预处理二进制位数
memset(dp, 0x3f, sizeof(dp)); dp[0]=0;
for (int i=0; i<(1<<tot); i++)
{
if (num[i]&1) continue;
int j=((1<<tot)-1)^i; j=low[j&-j]+1;
for (int k=j+1; k<=tot; k++)
dp[i|(1<<(j-1))|(1<<(k-1))]=
min(dp[i|(1<<(j-1))|(1<<(k-1))],
dp[i]+mn[j][k]);
}//状压
printf("%d\n",dp[(1<<tot)-1]==inf?-1:dp[(1<<tot)-1]);
return 0;
}
CF79D Password的更多相关文章
- Luogu 3943 星空
原题是CF79D Password 很妙的题. 首先我们发现区间操作不太好弄,我们想办法把它转化成单点操作,这样子处理的办法会多一点. 方法当然是差分了. 定义差分数组$b_i = a_i \^ a_ ...
- 一句话题解&&总结
CF79D Password: 差分.两点取反,本质是匹配!最短路+状压DP 取反是套路,匹配是发现可以把操作进行目的化和阶段化,从而第二次转化问题. 且匹配不会影响别的位置答案 sequence 计 ...
- 打开程序总是会提示“Enter password to unlock your login keyring” ,如何成功关掉?
p { margin-bottom: 0.1in; line-height: 120% } 一.一开始我是按照网友所说的 : rm -f ~/.gnome2/keyrings/login.keyrin ...
- your password has expired.to log in you must change it
今天应用挂了,log提示密码过期.客户端连接不上. 打开mysql,执行sql语句提示密码过期 执行set password=new password('123456'); 提示成功,但客户端仍然连接 ...
- MySql Access denied for user 'root'@'localhost' (using password:YES) 解决方案
关于昨天下午说的MySQL服务无法启动的问题,解决之后没有进入数据库,就直接关闭了电脑. 今早打开电脑,开始-运行 输入"mysql -uroot -pmyadmin"后出现以下错 ...
- [上架] iOS "app-specific password" 上架问题
当你的 Apple ID 改用双重认证密码时,上架 iOS App 需要去建立一个专用密码来登入 Apple ID 才能上架. 如果使用 Application Loader 上传时,得到这个讯息: ...
- [LeetCode] Strong Password Checker 密码强度检查器
A password is considered strong if below conditions are all met: It has at least 6 characters and at ...
- mysql 错误 ERROR 1372 (HY000): Password hash should be a 41-digit hexadecimal number 解决办法
MySQL创建用户(包括密码)时,会提示ERROR 1372 (HY000): Password hash should be a 41-digit hexadecimal number: 问题原因: ...
- phpmyadmin #1045 - Access denied for user 'root'@'localhost' (using password: NO)
phpmyadmin访问遇到1045问题 #1045 - Access denied for user 'root'@'localhost' (using password: NO) 解决办法 找到p ...
随机推荐
- javascript常用验证大全
1. 长度限制 <script> function test() { if(document.a.b.value.length>50) { alert("不能超过50个字符 ...
- outlook更改邮件存储路径
由于司邮箱容量磁盘配额很小,没收几封邮件就提示邮箱容量已满请删除不重要的邮件很是烦人,于是乎就想着怎么把邮件存到本地然后自动删除服务器上的邮件不做备份,这样就不会在提示邮箱容量已满了,就不用担心发不出 ...
- ORM是什么?如何理解ORM?
一.ORM简介 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.简单的说,ORM是通过使 ...
- java web作用域page request session application
转载自:http://blog.csdn.net/wyd458549392147/article/details/6944481 1.page指当前页面.只在一个jsp页面里有效 . 2.reques ...
- Bourne Shell:控制语句、条件判断、文本处理、常用命令
条件判断是一个程序获得智能的基础,而Bourne Shell脚本则通过命令 [ 来模拟大多数编程语言中的条件表达式. shell中支持的控制结构有: (1) if then else fi (2) f ...
- ArcGIS GP服务的发布及调用
参考https://www.jianshu.com/p/5331fa708fe5
- 怎样在Windows与Centos下的Linux间共享文件,如果mnt文件夹不显示,可能是mnt缺少共享支持
mnt中的hgfs文件夹就是Linux系统中挂载共享文件的默认文件夹.有的人按步骤共享之后mnt中没有出现共享的文件,可能是因为你的mnt缺少共享支持. 此时可以在Terminal中输入:sudo m ...
- numpy中三维数组转变成二维数组
numpy中reshape()函数对三维数组进行转换成二维数组,见下面例子: >>>a=np.reshape(np.arange(18),(3,3,2)) >>> ...
- docker daemon文件/etc/docker/daemon.json配置
On Linux The default location of the configuration file on Linux is /etc/docker/daemon.json. The --c ...
- Android的/system/lib里加入自己的so库
执行下命令: 1 重新挂载/system目录,使之能读写:mount -o remount,rw /dev/null /system 2 修改这个文件的权限:chmod 777 /system 3 利 ...