洛谷mNOIP模拟赛Day2-星空
题目背景
pdf题面和大样例链接:http://pan.baidu.com/s/1cawM7c 密码:xgxv
命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷。
你来过,然后你走后,只留下星空。
题目描述
逃不掉的那一天还是来了,小 F 看着夜空发呆。
天上空荡荡的,没有一颗星星——大概是因为天上吹不散的乌云吧。
心里吹不散的乌云,就让它在那里吧,反正也没有机会去改变什么了。
小 C 拿来了一长串星型小灯泡,假装是星星,递给小 F,想让小 F 开心一点。不过,有 着强迫症的小 F 发现,这串一共 n 个灯泡的灯泡串上有 k 个灯泡没有被点亮。小 F 决定 和小 C 一起把这个灯泡串全部点亮。
不过,也许是因为过于笨拙,小 F 只能将其中连续一段的灯泡状态给翻转——点亮暗灯 泡,熄灭亮灯泡。经过摸索,小 F 发现他一共能够翻转 m 种长度的灯泡段中灯泡的状态。
小 C 和小 F 最终花了很长很长很长很长很长很长的时间把所有灯泡给全部点亮了。他 们想知道他们是不是蠢了,因此他们找到了你,让你帮忙算算:在最优的情况下,至少需要 几次操作才能把整个灯泡串给点亮?
输入输出格式
输入格式:
从标准输入中读入数据。
输入第 1 行三个正整数 n,k,m。
输入第 2 行 kk 个正整数,第 i 个数表示第 i 个被没点亮的灯泡的位置 a_iai。
输入第 3 行 mm 个正整数,第 i 个数表示第 i 种操作的长度 b_ibi。
保证所有 b_ibi 互不相同;保证对于 1 \le i < k1≤i<k,有 a_i< a_i+1ai<ai+1;保证输入数据有解。
输出格式:
输出标准输入中。
输出一行一个非负整数,表示最少操作次数。
输入输出样例
说明
【样例 1 解释】

【数据范围与约定】
子任务会给出部分测试数据的特点。如果你在解决题目中遇到了困难,可以尝试只解 决一部分测试数据。
每个测试点的数据规模及特点如下表

特殊性质:保证答案小于 4
不妨就暴力一点吧。。。
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#define INF 0x7f7f7f7f
#define pii pair<int,int>
#define ll long long
#define MOD 19260817
using namespace std;
int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if('-'==ch)f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct Node{
int cost;
int sum;
int a[];
Node(int p1=,int p2=,int b[]={}){
cost=p1;
sum=p2;
memcpy(a,b,sizeof(a));
}
};
ll hash(Node t){
ll ret=;
for(int i=;i<=;i++){
ret=((ret<<)+t.a[i])%MOD;
}
return ret;
}
set<ll> s;
int n,k,m;
int L[];
queue<Node> q;
void init(){
n=read(),k=read(),m=read();
int t[]={};
for(int i=;i<=k;i++){
t[read()]=;
}
for(int i=;i<=m;i++){
L[i]=read();
}
q.push(Node(,k,t));
s.insert(hash(Node(,k,t)));
}
void solve(){
while(!q.empty()){
int a[]={};
int cost=q.front().cost;
int sum=q.front().sum;
memcpy(a,q.front().a,sizeof(a));
q.pop();
for(int i=;i<=m;i++){
for(int j=;j<=n-L[i]+;j++){
int b[]={},dsum=sum;
memcpy(b,a,sizeof(b));
for(int l=j;l<=j+L[i]-;l++){
if(!b[l]){
dsum++;
}
else{
dsum--;
}
b[l]=(!b[l]);
}
if(!dsum){
printf("%d\n",cost+);
return;
}
Node t=Node(cost+,dsum,b);
ll h=hash(t);
if(s.count(h)){
continue;
}
q.push(t);
s.insert(h);
}
}
}
}
int main()
{
// freopen("starlit2.in","r",stdin);
init();
solve();
return ;
}
太暴力啦QAQ
考虑正解:
首先我们知道异或满足差分的性质:可逆性
从本质上来说,异或就是取反的过程,所以正过来可以,反过去也是可以了
这样就把一段区间取反转化为端点取反了。
问题转化为:
给定一个长度为n的0-1序列,最多包含2k个1,每次可以把间隔一定长度的两个位置取反,求最少多少次把序列全部变成0
然后我们发现,肯定是要对1操作的,不可能平白无故地把两个0取反(尽管最后的结果与操作顺序无关,但这里考虑下操作顺序)
如果是1和0的话,就可以看成1转移到了0的位置并花费了一次操作的代价
如果是1和1的话,就可以看成1转移到了另一个1的位置,然后两个1都消去了并花费了一次操作的代价
这样问题转化为:
给定一个长度为n的0-1序列,最多包含2k个1,每次可以把1转移到相距一定长度的位置,如果两个1在同一位置就会消去,求最少多少次把序列全部变成0
进一步转化为:
给定一个n个节点的图,其中最多2k的节点有物品,每次可以把一件物品转移到相距一定长度的位置,如果一个节点出现两个物品就会消去,求最少多少次把物品全部消除
我们可以用2k次bfs处理出每个物品与另外所有物品消去的代价,
这样问题转化为:
给定2k个物品,其中每2个物品消去都会消耗一定的代价,求把所有物品消去的最小代价
这样就是状压dp了,可以用SPFA来解决
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define MAXK 9
#define MAXN 40005
#define pii pair<int,int>
using namespace std;
int read(){
int x=;char ch=getchar();
while(ch<''||ch>''){ch=getchar();}
while(ch>=''&&ch<=''){x=x*+(ch^);ch=getchar();}
return x;
}
int n,k,m;
int a[MAXN],b[MAXN],ed[MAXN];
int Cost[MAXK<<][MAXK<<];
int cnt;
int len[];
vector<int> v;
void init(){
n=read();k=read();m=read();
for(int i=;i<=k;i++){
a[read()]=;
}
n++;
for(int i=;i<=n;i++){
b[i]=a[i]^a[i-];
}
for(int i=;i<=n;i++){
if(b[i]){
b[i]=(++cnt);
v.push_back(i);
}
}
for(int i=;i<=m;i++){
len[i]=read();
}
}
queue<pii> q;
void bfs(){
memset(Cost,-,sizeof(Cost));
for(int z=;z<v.size();z++){
int x=v[z];
memset(ed,-,sizeof(ed));
while(!q.empty()) q.pop();
q.push(make_pair(x,));
ed[x]=;
while(!q.empty()){
int t=q.front().first;
int c=q.front().second;
q.pop();
for(int i=;i<=m;i++){
for(int j=-;j<=;j+=){
int dt=t+j*len[i];
if(<=dt&&dt<=n&&-==ed[dt]){
ed[dt]=c+;
if(b[dt]){
Cost[b[x]][b[dt]]=ed[dt];
}
q.push(make_pair(dt,ed[dt]));
}
}
}
}
}
}
queue<int> Q;
int dp[<<(MAXK*)];
int used[<<(MAXK*)];
void solve(){
memset(dp,0x7f,sizeof(dp));
dp[(<<cnt)-]=;
Q.push((<<cnt)-);
used[(<<cnt)-]=;
while(!Q.empty()){
int t=Q.front();
Q.pop();
used[t]=;
for(int i=;i<cnt;i++){
if((t>>(i-))&){
for(int j=i+;j<=cnt;j++){
if((t>>(j-))&){
int dt=t;
dt^=(<<(i-));
dt^=(<<(j-));
if(Cost[i][j]!=-&&dp[dt]>dp[t]+Cost[i][j]){
dp[dt]=dp[t]+Cost[i][j];
if(!used[dt]){
Q.push(dt);
used[dt]=;
}
}
}
}
}
}
}
printf("%d\n",dp[]);
}
int main()
{
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
init();
bfs();
solve();
return ;
}
AC
以上为正解思路,这也揭示了题目的本质
总结:很好的一道题,考察较高的思维能力
洛谷mNOIP模拟赛Day2-星空的更多相关文章
- 洛谷mNOIP模拟赛Day1-斐波那契
题目背景 大样例下发链接:http://pan.baidu.com/s/1c0LbQ2 密码:jigg 题目描述 小 C 养了一些很可爱的兔子. 有一天,小 C 突然发现兔子们都是严格按照伟大的数学家 ...
- 洛谷mNOIP模拟赛Day1-分组
传送门 首先是贪心的思路 从后向前选,能多选就多选, 理由:数字越少肯定越优,同时间隔尽量向前推,字典序尽量小 对于K==1,枚举1~512直接判断 对于K==2,需要用镜像并查集,来刻画" ...
- 洛谷mNOIP模拟赛Day2-将军令
题目背景 pdf题面和大样例链接:http://pan.baidu.com/s/1cawM7c 密码:xgxv 历史/落在/赢家/之手 至少/我们/拥有/传说 谁说/败者/无法/不朽 拳头/只能/让人 ...
- 洛谷mNOIP模拟赛Day2-入阵曲
题目背景 pdf题面和大样例链接:http://pan.baidu.com/s/1cawM7c 密码:xgxv 丹青千秋酿,一醉解愁肠. 无悔少年枉,只愿壮志狂. 题目描述 小 F 很喜欢数学,但是到 ...
- 洛谷mNOIP模拟赛Day1-数颜色
传送门 题目大意: 给定一个序列,维护每个数字在[L,R]出现的次数以及交换a[x]和a[x+1]的操作 一开始想的分桶法,感觉复杂度还可以吧,常数有点大,于是死得很惨(65分) #include&l ...
- 【洛谷mNOIP模拟赛Day1】T1 斐波那契
题目传送门:https://www.luogu.org/problemnew/show/P3938 这题出得特别吼啊~~ 通过打表或者大胆猜想斐波那契数列的一些性质,我们不难发现对于一只兔子$x$,其 ...
- 洛谷noip 模拟赛 day1 T3
T7983 大芳的逆行板载 题目背景 大芳有一个不太好的习惯:在车里养青蛙.青蛙在一个n厘米(11n毫米s)的Van♂杆子上跳来跳去.她时常盯着青蛙看,以至于突然逆行不得不开始躲交叉弹.有一天他突发奇 ...
- 洛谷noip 模拟赛 day1 T1
T7925 剪纸 题目描述 小芳有一张nnn*mmm的长方形纸片.每次小芳将会从这个纸片里面剪去一个最大的正方形纸片,直到全部剪完(剩下一个正方形)为止. 小芳总共能得到多少片正方形纸片? 输入输出格 ...
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
随机推荐
- Beta冲刺第二天
一.昨天的困难 没困难 二.今天进度 局部测试并修复出现的bug 1.林洋洋:修复登录页面显示问题,修复日程查询问题 2.黄腾达:修复创建协作开始时间和结束时间没做检验的问题 3.张合胜:修复页面内容 ...
- 团队第1次作业:Our Team TAH
Team named TAH 不管一个人多么有才能,但是集体常常比他更聪明和更有力. --奥斯特洛夫斯基 *introduce team and teamate 先说说TAH的含义,是 ...
- 1013团队Beta冲刺day5
项目进展 李明皇 今天解决的进度 服务器端还未完善,所以无法进行联动调试.对页面样式和逻辑进行优化 明天安排 前后端联动调试 林翔 今天解决的进度 完成维护登录态,实现图片上传,微信开发工具上传图片不 ...
- python的Flask 介绍
Flask 介绍 知识点 微框架.WSGI.模板引擎概念 使用 Flask 做 web 应用 模板的使用 根据 URL 返回特定网页 实验步骤 1. 什么是 Flask? Flask 是一个 web ...
- 乐动力APP案例
第一部分 调研, 评测 下载软件并使用起来,描述最简单直观的个人第一次上手体验. 这款软件的主界面功能还是比较完善,里面有多个关于运动相关的数据,还有一些推荐健身教程,记录功能也十分不错,其中最难理解 ...
- Hibernate之深入Hibernate的映射文件
这周周末 要把hibernate的映射文件搞定 .. 1.映射文件的主结构 主要结构 :根元素为<hibernate-mapping ></hibernate-mapping> ...
- shell中冒号 : 用途说明
我们知道,在Linux系统中,冒号(:)常用来做路径的分隔符(PATH),数据字段的分隔符(/etc/passwd)等.其实,冒号(:)在Bash中也是一个内建命令,它啥也不做,是个空命令.只起到占一 ...
- Java KeyTool command
Create a new key: keytool -genkey -alias keyAlias -keyalg RSA -validity 1000 -keystore d:\keyPath\k ...
- 第5章 子网划分和CIDR
第5章 子网划分和CIDR 划分网络 根据A类.B类或C类网络ID来识别网段具有一些局限性,主要是在网络级别之下不能对地址空间进行任何逻辑细分 如果一个IP是一个A类网络.数据报到达网关,然后传输到9 ...
- jhipster生成项目无法使用restful请求,报access_denied 403错误
写在前边: 我们的微服务是注册中心.uaa.gateway为基础,添加微服务应用,昨天下午在测试jhipster的增删改查,因为jhipster生成的代码都是restful的,好不容易找到网关配置的映 ...