2019.08.12【NOIP提高组】模拟 B 组 模拟+DP+差分约束、spfa
文章目录
- 0 少女觉
- 1 灵知的太阳信仰
- 2 多段线性函数
- 3 DY引擎
- 差分约束系统
- 我很喜欢你,我会一直喜欢你到你不再需要我喜欢你为止。——顾飞
0 少女觉
在幽暗的地灵殿中,居住着一位少女,名为古明地觉。
据说,从来没有人敢踏入过那座地灵殿,因为人们恐惧于觉一族拥有的能力——读心。
掌控人心者,可控天下。
咳咳。
人的记忆可以被描述为一个黑块(B)与白块(W)的序列,其中情感值被定义为序列中黑块数量与白块数量之比。
小五口在发动读心术时,首先要解析人的记忆序列,因此,需要将序列分割为一些段,并且要求每一段记忆序列的情感值都相等。
下面给出两个例子:
BWWWBB -> BW + WWBB (Ratio=1:1)
WWWBBBWWWWWWWWWB -> WWWB + BBWWWWWW + WWWB (Ratio=3:1)
现在小五手上有一个人的记忆序列,她想要知道,如何将手中的记忆序列分成尽可能多的段呢?
对于10%的数据,n<=15
对于20%的数据,n<=500
另有30%的数据,K=1
另有30%的数据,K<=50
对于100%的数据,N<=10^5 , 序列长度不超过10^9
保证对于全部测试点,输入文件行数不超过2.5*10^6
可以发现黑块与白块的比是确定的,是所有黑块比上所有白块,因而每一个小序列的比就是这个总比值
那么就按读入顺序往下做,每次一满足比值就马上记录答案
#include <cstdio>
#include <algorithm>using namespace std;int t,n,ans;
long long suma,sumb,wa,wb,p;
int a[100005],b[100005];void read(int i){char ch=getchar();a[i]=0;while (ch<'0'||ch>'9') ch=getchar();while (ch>='0'&&ch<='9'){a[i]=a[i]*10+ch-'0';ch=getchar();}while (ch!='B'&&ch!='W') ch=getchar();if (ch=='B') b[i]=1,sumb+=a[i]; else b[i]=0,suma+=a[i];
}long long pk(long long s,long long a,long long b){if ((a*s)%b==0) return (a*s)/b; else return -1;
}int main(){freopen("silly.in","r",stdin);freopen("silly.out","w",stdout);scanf("%d",&t);for (;t;t--){scanf("%d",&n);suma=0,sumb=0,ans=0;for (int i=1;i<=n;i++){read(i);}if (suma==0||sumb==0){printf("%d\n",max(suma,sumb));continue;}wa=0;wb=0;for (int i=1;i<=n;i++){if (b[i]==0) {long long p=pk(wb,suma,sumb);if (p>wa&&p<=wa+a[i]) ans++;wa+=a[i];}else {long long p=pk(wa,sumb,suma);if (p>wb&&p<=wb+a[i]) ans++;wb+=a[i];}}printf("%d\n",ans); }
}
1 灵知的太阳信仰
在炽热的核熔炉中,居住着一位少女,名为灵乌路空。
据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量——核能。
核焰,可融真金。
咳咳。
每次核融的时候,空都会选取一些原子,排成一列。然后,她会将原子序列分成一些段,并将每段进行一次核融。
一个原子有两个属性:质子数和中子数。
每一段需要满足以下条件:
1、同种元素会发生相互排斥,因此,同一段中不能存在两个质子数相同的原子。
2、核融时,空需要对一段原子加以防护,防护罩的数值等于这段中最大的中子数。换句话说,如果这段原子的中子数最大为x,那么空需要付出x的代价建立防护罩。求核融整个原子序列的最小代价和。
设 f[i] 为 i 与 i+1 之间分开,到i为止的代价和
预处理出 l[i] 表示 i 最早的相同质子数的位置
易得f[i]=min(f[j]+b[j+1——i]),l[i]<j<=if[i]=min(f[j]+b[j+1 ——i]),l[i]<j<=if[i]=min(f[j]+b[j+1——i]),l[i]<j<=i,这样的转移是O(n2)O(n^2)O(n2)的
可以用单调队列维护合法的点组成的队列,每次更新f[i]只需循环合法的点,每次又都取出不合法的点
因为前一个点不能转移的点,后一个点也不能通过这个点转移来
(因为可能TLE所以稍微卡了个常?)
比如register , 快读 ,if 改为(xx条件xx?xx:xx)
#include <cstdio>
#include <algorithm>using namespace std;const int N=100005;
const int inf=2000000000;
int n;
int l[N],p[N],w[N];
int f[N],e[N];int read(){char ch=getchar();while (ch<'0'||ch>'9') ch=getchar();int x=0;while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x;
}int main(){freopen("array.in","r",stdin);freopen("array.out","w",stdout);n=read();int ab;for (register int i=1;i<=n;i++){ab=read();w[i]=read();l[i]=(l[i-1]>p[ab]?l[i-1]:p[ab]),p[ab]=i,f[i]=inf;}int h=1,t=1;f[1]=w[1],e[1]=1;for (register int i=2;i<=n;i++){while (h<=t&&e[h]<=l[i]) ++h;while (h<=t&&w[i]>w[e[t]]) --t;e[++t]=i;for (int j=h+1;j<=t;j++)f[i]=(f[i]>f[e[j-1]]+w[e[j]]?f[e[j-1]]+w[e[j]]:f[i]); f[i]=(f[i]>f[l[i]]+w[e[h]]?f[l[i]]+w[e[h]]:f[i]);} printf("%d",f[n]);
}
2 多段线性函数
哎嗨,据dalao言此题是为阅读题
就,题目的函数公式,相当于y到每个区间的距离
因为要求的函数值尽可能小,所以当y在区间内xi肯定是取y ,这时对函数值无贡献;当y不在区间内xi也一定是取与y更近的端点
所以就只与端点有关
就把所有端点堆一起排个序,取中间两个就是答案
啊哈,中位数
#include <cstdio>
#include <algorithm>using namespace std;int n;
int a[200005];int main(){freopen("linear.in","r",stdin);freopen("linear.out","w",stdout);scanf("%d",&n);for (int i=1;i<=n;i++)scanf("%d%d",&a[i],&a[i+n]);sort(a+1,a+1+n*2);printf("%d %d",a[n],a[n+1]);
}
3 DY引擎
BOSS送给小唐一辆车。小唐开着这辆车从PKU出发去ZJU上课了。
众所周知,天朝公路的收费站超多的。经过观察地图,小唐发现从PKU出发到ZJU的所有路径只会有N(2<=N<=300)个不同的中转点,其中有M(max(0, N-100) <=M<=N)个点是天朝的收费站。N个中转点标号为1…N,其中1代表PKU,N代表ZJU。中转点之间总共有E(E<=50,000)条双向边连接。
每个点还有一个附加属性,用0/1标记,0代表普通中转点,1代表收费站。当然,天朝的地图上面是不会直接告诉你第i个点是普通中转点还是收费站的。地图上有P(1<=P<=3,000)个提示,用[u, v, t]表示:[u, v]区间的所有中转点中,至少有t个收费站。数据保证由所有提示得到的每个点的属性是唯一的。
车既然是BOSS送的,自然非比寻常了。车子使用了世界上最先进的DaxiaYayamao引擎,简称DY引擎。DY引擎可以让车子从U瞬间转移到V,只要U和V的距离不超过L(1<=L<=1,000,000),并且U和V之间不能有收费站(小唐良民一枚,所以要是经过收费站就会停下来交完钱再走)。
DY引擎果然是好东西,但是可惜引擎最多只能用K(0<=K<=30)次。
这题可以拆分成两部分,找出收费站和找出最短路
其中找出收费站需要用到差分约束系统
差分约束系统
用于题目给出形如:a[i]−a[j]<=ka[i]-a[j]<=ka[i]−a[j]<=k 的约束条件,求a[i]a[i]a[i]状态
首先我们荡开笔墨,先假设我们有一张有向图,已经求出了最短路,a[i]a[i]a[i]表示从1到i的最短路
现在有一条i到j的边,表示为dis[i][j]dis[i][j]dis[i][j]
当然有a[j]−a[i]<=dis[i][j]a[j]-a[i]<=dis[i][j]a[j]−a[i]<=dis[i][j]
那么我们反过来,回到给出的约束条件a[i]−a[j]<=ka[i]-a[j]<=ka[i]−a[j]<=k,就相当于从j到i连一条权值为k的有向边
求出a[i]a[i]a[i]的状态当然也就是用最短路,快乐跑spfa
当然有很多题目不会直接给出约束条件,要自己从题目描述中找
再回到这道题
条件:[u, v]区间的所有中转点中,至少有t个收费站
设s[i]s[i]s[i]表示111到iii的收费站总数,则条件转化为s[v]−s[u−1]>=ts[v]-s[u-1]>=ts[v]−s[u−1]>=t
再移下项,就是s[u−1]−s[v]<=ts[u-1]-s[v]<=ts[u−1]−s[v]<=t
这就相当于差分约束系统的条件了,求出s[i]s[i]s[i]状态后s[i]−s[i−1]s[i]-s[i-1]s[i]−s[i−1]即为iii是否有收费站
然后就是用最短路跑DP啦
跑这个最短路呢,要记录第几个点,跳了几次
#include <cstdio>
#include <cstring>using namespace std;const int N=50002;
int n,m,e,p,l,k;
int ls[305],ne[N],y[N],w[N],bz[305],cnt;
int s[305],v[N*10],g[N*10],b[N][35],d[N*10];
int f[305][35],a[305][305];void ad(int _u,int _v,int _w){ne[++cnt]=ls[_u],ls[_u]=cnt,y[cnt]=_v,w[cnt]=_w;
}void spfa1(){memset(s,0x3f,sizeof s);for (int i=1;i<=n;i++)ad(i,i-1,0),ad(i-1,i,1);int h=0,t=1;v[1]=n;s[n]=m;bz[n]=1;while (h<t){int u=ls[v[++h]];while (u!=-1){if (s[v[h]]+w[u]<s[y[u]]){s[y[u]]=s[v[h]]+w[u];if (bz[y[u]]==0){bz[y[u]]=1;v[++t]=y[u];}}u=ne[u];}bz[v[h]]=0;}for (int i=n;i>=1;i--) s[i]=s[i]-s[i-1];
}void read(){scanf("%d%d%d%d%d%d",&n,&m,&e,&p,&l,&k);memset(a,0x3f,sizeof a);for (int i=1;i<=e;i++){int u,_v,_w;scanf("%d%d%d",&u,&_v,&_w);if (_w<a[u][_v]) a[u][_v]=a[_v][u]=_w;}for (int i=0;i<=n;i++) ls[i]=-1;for (int i=1;i<=p;i++){int _u,_v,_t;scanf("%d%d%d",&_u,&_v,&_t); ad(_v,_u-1,-_t); }
}void floyed(){for (int k=1;k<=n;k++)for (int i=1;i<=n;i++)if (i!=k)for (int j=1;j<=n;j++) if (i!=j&&j!=k&&s[k]==0&&a[i][k]!=a[0][0]&&a[k][j]!=a[0][0])a[i][j]=(a[i][j]>a[i][k]+a[k][j]?a[i][k]+a[k][j]:a[i][j]);
}void spfa2(){cnt=0;int h=0,t=1;memset(b,0,sizeof b); memset(f,0x3f,sizeof f);b[1][0]=1,f[1][0]=0;v[1]=1,d[1]=0;while (h<t){int x=v[++h],y=d[h];for (int i=2;i<=n;i++)if (a[x][i]!=a[0][0]){if (f[x][y]+a[x][i]<f[i][y]){f[i][y]=f[x][y]+a[x][i];if (b[i][y]==0){b[i][y]=1;v[++t]=i;d[t]=y;}}if (y+1<=k&&a[x][i]<=l&&f[x][y]<f[i][y+1]){f[i][y+1]=f[x][y];if (b[i][y+1]==0){b[i][y+1]=1;v[++t]=i;d[t]=y+1;}}}b[x][y]=0;}
}void print(){int ans=1000000000;for (int i=0;i<=k;i++)ans=(ans>f[n][i]?f[n][i]:ans);printf("%d",ans);
}int main(){read();spfa1(); floyed();spfa2(); print();
}
我很喜欢你,我会一直喜欢你到你不再需要我喜欢你为止。——顾飞
2019.08.12【NOIP提高组】模拟 B 组 模拟+DP+差分约束、spfa相关推荐
- 2018.12.08【NOIP提高组】模拟B组总结(未完成)
2018.12.08[NOIP提高组]模拟B组总结 diyiti 保留道路 进化序列 B diyiti Description 给定n 根直的木棍,要从中选出6 根木棍,满足:能用这6 根木棍拼出一个 ...
- 2020.08.08【NOIP提高组】模拟:奶牛的图片 总结
2020.08.08[NOIP提高组]模拟:奶牛的图片 总结 Description Farmer John希望给他的 N ( 1 ≤ N ≤ 100 , 000 ) N(1\leq N\leq100 ...
- 【题解】少女觉 (2019.08.12纪中【NOIP提高组】模拟 B 组T1)贪心
题目来源:中山纪念中学 题目描述: 在幽暗的地灵殿中,居住着一位少女,名为古明地觉. 据说,从来没有人敢踏入过那座地灵殿,因为人们恐惧于觉一族拥有的能力--读心. 掌控人心者,可控天下. 咳咳. 人的 ...
- 2019.08.12【NOIP提高组】模拟 A 组
解题报告 JZOJ 6293 迷宫 题目 分析 代码 JZOJ 6297 猛汉王 题目 分析 代码 JZOJ 6299 工厂 题目 分析 代码 JZOJ 6293 迷宫 题目 分析 因为其没有后效性 ...
- 2019.8.12 NOIP模拟测试18 反思总结
写个博客总是符合要求的对吧 回来以后第一次悄悄参加考试,昨天全程围观- 然后喜提爆炸120分wwwwwwwww T1用了全机房最慢的写法,导致改掉死循环T掉的一个点以后还是死活过不了最后一个点.T2全 ...
- 【每日早报】2019/08/12
今日看点 ✦ 头条搜索网页版悄然上线,广告语为"搜你想搜的" ✦ 唯品仓更名"唯代购",更精准服务代购群体 ✦ 华为视频发布"百花号":砸亿 ...
- 天梯赛基础题型详解(2019 - 08 - 12)
A.枚举 (1) 详解:用枚举法,从最开始的只有一层沙漏开始枚举,直至找到一个沙漏所用符号的总和小于等于输入的数(将每一次不同层数的沙漏的符号和都用数组储存起来),然后标记那个最大的和.要注意的是每增 ...
- SUST 2019暑期集训题解(差分约束+生成树+传递闭包)
A 这个不等式组很眼熟吧 这道题的话上课讲过就是根据不等式建图然后跑一下最短路就可以了. #include<iostream> #include<cstring> #inclu ...
- 第一届『Citric杯』NOIP提高组模拟赛 题解
[官方题解]第一届『Citric杯』NOIP提高组模拟赛 题解 第一题 柠檬超市 这题是本次模拟赛的送分题.做法显然. 但是注意此题有一个陷阱: 注意W和C的规模都是10^9,所以如果直接用doubl ...
最新文章
- 两分钟用C#搭建IE BHO勾子, 窃取密码
- Selenium之定位浏览器弹窗方法汇总
- Leetcode970. Powerful Integers强整数
- Unity网络:在局域网P2P网络中利用UDP广播实现保活/心跳
- 赛锐信息:SuccessFactors激活高效能人员战略
- 低功耗电池电压ADC采样电路,墨水屏通电掉电控制电路,PMOS电子开关,可用于待机低功耗的项目
- c++ main函数调用 类中的枚举_为什么 Java 的 main 方法必须是 public static void?
- Java 学习笔记(官方不推荐写法篇)
- 小程序swiper效果高宽设置(微信小程序交流群:604788754)
- shell命令 安装软件包
- 【教程】如何在C#中创建PDF417条码
- 什么是超级浏览器?有什么作用?如何选择?
- 看完左耳朵耗子的116篇文章,我给自己定了个5年技术规划
- python实现的广域网聊天(无需搭建服务器,基于FICS和socket模块)
- 三相全桥整流电路_什么是三相桥式全控整流电路,三相桥式全控的工作原理是什么,三相桥式全控电路电路图...
- 5年后端WEB开发者的开机必备软件(md版本)
- DM6467T移植图像算法
- c++工程error lnk2001解决方法
- win10+centos7双系统安装总结
- 什么样内容的书值得买纸质书
热门文章
- DBeaver SQL format 第三方插件方案
- 制作老毛桃启动盘教程
- python中arcsec_python绘制基本初等函数图像
- [原创]WIN8系统的远程桌面漏洞 利用QQ拼音纯净版实现提权
- 从DataSet 导出到Excel(是DataSet中的每个DataTable对应每个Sheet)
- GLES2.0中文API-glBindFramebuffer
- 基于YOLOV3的通用物体检测项目实战---(5)利用DarkNet框架进行YOLOV3模型训练实操(笔记)
- C++多态的好处和作用(用实例说话)
- linux 批量 添加后缀名,Linux下批量修改后缀名(示例代码)
- linux gcc忽略警告,gcc 禁止warning