洛谷 P2882
题意:
N头牛排成一列1<=N<=5000。每头牛或者向前或者向后。为了让所有牛都 面向前方,农夫每次可以将K头连续的牛转向1<=K<=N,求操作的最少 次数M和对应的最小K。
思路:
想要将所有的牛全部朝向一个方向。
试想:如果不从头开始考虑,那么如果头部有牛牛朝后,那么要对头部的牛牛调整的时候必将会使已经调好方向的牛牛变动方向。
为了表示方便,我们用0、1表示朝后、朝前。
那么对于每一个确定的k(k头连续的牛),我们就从前往后,遇见一个0,就使从其开始的k头牛变换方向。直到超出边界条件为止!(唯一的中止条件。。
否则,如果遍历一遍队列还没有中止,记录sum(次数)最小值以及对应的k值。
明显地,时间复杂度是O(N^3)。
- k从1到n。
- 遍历从头到尾。
- 对于每一个0开头的数要标记之后的K个值
对于5000的数据规模,O(N^3)显然是很危险的复杂度。
一定会TLE~
改进方案:
如果能对第三个N:
对于每一个0开头的数要标记之后的K个值
简化为O(1)的时间复杂度,这个问题就好解决了。
标记!想到差分!
差分思路:对于每一个遇到的0,都将tag标记+1;在第k个牛牛处标记一下,当遍历到该处时,tag–。
丑陋的代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <math.h>
#include <functional>
#include <string>
#include <vector>
#include <map><