分析:一辆车最多载k个人,车的速度肯定比人快,所以想要到达时间最短,那么每个人必须做一次公交车.那么把n个人分成p=(n+k-1)/k组.设最短时间为t,每人乘车时间为t1,则t1*v2+(t-t1)*v1=L.设每次车子返回走的时间为t2,则(t1+t2)*v1+t2*v2=t1*v2.由这两个式子可以写出t1,t2的表达式.又因为p*t1+(p-1)*t2=t. 所以可以以最短时间L/v2为左端值,以L/v1为右端值二分t. #include <iostream> #include <…
[Codeforces 865C]Gotta Go Fast(期望dp+二分答案) 题面 一个游戏一共有n个关卡,对于第i关,用a[i]时间通过的概率为p[i],用b[i]通过的时间为1-p[i],每通过一关后可以选择继续下一关或者时间清0并从第一关开始,先要求通过所有关卡的时间和不能超过R才算彻底通关,问直到彻底通关位置的游戏时间的期望值为多少 分析 二分从头开始通关的用时期望mid 设\(dp[i][j]\)表示通前i关,当前时间为j的期望,倒推期望. 若超时重新开始,则\(dp[i][j]…
[题目链接] http://codeforces.com/problemset/problem/700/A [题目大意] 有一辆限载k人速度为v2的车,n个步行速度均为v1的人要通过一段长度为l的距离,每个人只能上车一次,车可以来回走,问所有人到达目的地所需要的最短时间是多少 [题解] 因为车可以载k个人,所以,我们把人k个为一组分成(n+k-1)/k组,记为p吗,设需要的最短时间为t,每个人在车上待的时间为t2,那么可以列方程v1*(t-t2)+v2*t2=l,我们可以发现t2可以用t来表示,…
<题目链接> 题目大意: 给定起点和终点,某艘船想从起点走到终点,但是海面上会周期性的刮风,船在任何时候都能够向四个方向走,或者选择不走,船的真正行走路线是船的行走和风的走向叠加的,求船从起点到终点的最小步数. 解题分析: 因为本题数据量十分大,并且船和风叠加的行走路线比较复杂,所以我们考虑用二分答案解题.因为从起点到终点的有效步数是一定的,所以我们可以将船走动的总步数与风的步数(风吹不动的船的步数)分别进行计算,因为风是周期性吹的,但是从起点走到终点不一定是整数个周期,所以我们需要记录每个周…
这是最大化最小值的一类问题,这类问题通常用二分法枚举答案就行了. 二分答案时,先确定答案肯定在哪个区间内.然后二分判断,关键在于怎么判断每次枚举的这个答案行不行. 我是用a[i]数组表示初始时花的高度,b[i]表示要达到当前枚举的答案(即mid的值)需要这朵花再涨多少.这两个数组很好算,关键是一次浇连续的w朵花,如何更新区间(暴力的O(n2)的去更新就超时了)?可以用线段树,但是这道题没有涉及区间查询,就是在一个数组上更新区间,用线段树未免小题大做.那么其实这种更新就用延迟标记的思想(懒操作)就…
题目大意 可以理解成有n个木板,可以选取木板将其劈成2半(如果长度是奇数,就切成x和x+1),切完之后还可以再切 然后你要把这n个木板切成更多的木板,然后从中选择k个,使得这k个木板的最小长度尽量大 这个题有两种做法,不过都需要二分答案 先二分最小长度是x 第一种做法是 枚举n个木板,每一个都切到不能再切为止,然后统计有多少个木板,看能否符合 统计过程中要记录两个值,因为一个木板不论切多少次,结果都只会存在两种木板,然后记录一下每次切是哪两种木板以及各有多少个,然后简单转移即可 复杂度是nlog…
题目大意 给定一个序列an,序列中只有1~8的8个整数,让你选出一个子序列,满足下列两个要求 1.不同整数出现的次数相差小于等于1 2.子序列中整数分布是连续的,即子序列的整数必须是1,1,1....1,2,2,2.....2,2.......连续分布 做法: 那么我们可以二分不同整数出现的次数,假如说二分出现次数是L,那么可以证明有a个整数出现次数是L,有(8-a)个整数出现次数是L-1(同时不难证明L+1比L更优) 这样每个整数只有两种状态,要么选L个,要么选L-1个. 压缩决策s,s的第i…
要保证总时间最短,因为总时间计的是最后一个人到达的时间,也就是最后一个人要求尽快到达,也就是说我们要让最后一个人乘车时间尽量多.再仔细想想可以发现每个人的乘车时间和走路时间都是一样的. 因此,可以二分每个人的乘车时间$m$,然后进行验证,如果发现某一个人的乘车时间不到$m$,那么$m$不可取,上界缩小:如果$m$可取,那么上界增大. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio>…
题意:n个人要运动ll长,有个bus带其中几个人,问最短时间 最后所有人在同一时间到终点是用时最少的.由于搭bus相当于加速,每个人的加速时间应该一样.先计算bus走过的路程route.看第一个人被搭t分钟(也就是所有人以后都搭t分钟),剩余的人走t分钟,route+=v2*t.bus到了v2*t的位置,人在v1*t的位置.bus回去接人,被接的人继续前进.route2=(v2*t-v1*t)/(v1+v2)*v2(相向而行).接到人后再走v2*t,结果就是这样往复.最后一次不回头.如果要接a次…
题目:Problem - C - Codeforces 本题的优解是二分答案,但我其实不会二分,本质是用了两个指针作为边界,然后不断对半缩小范围来快速确定答案. 神奇的二分法 代码: #include <iostream> using namespace std; typedef long long ll; ll a[110]; ll n, h; bool check(ll k) { ll t = h - k; for (int i = 2; i <= n; ++i) { t -= mi…