https://www.luogu.org/problem/P2882

题意

你有n头牛,每头牛有个朝向,你每次可以选择连续k头牛翻转,求k为多少时可以用最少的步骤将所有牛朝向变为正向

n≤5000

分析

我们知道, 对于一个序列,我们如果选择每次翻k头牛,最优的翻转策略就是,每次找到第一头反向的牛,然后将它和后面的牛,一共k头都翻转,然后再往后找到第一个反向的牛,再...(因为每头牛都要翻正,如果先找到的是第一头反向的牛的前面或后面的牛翻转,那么就会造成额外的操作)

于是我们的做法是暴力枚举k,然后check出最佳的m,然而O(n^3)(check是O(nk)的),显然过不去,需要优化。

我们可以利用1为正向,0为反向,然后一个差分,用一个延迟标记tag,每次判断的时候用原数加上这个tag, 结果如果是奇数,就说明是正向的, 就不操作;如果是偶数,就是反向的,这时候操作数m++, 然后在翻转的右边界的右一个打上一个差分标记cf[i+k]=-1,而且我们cf的初值为0,这样就可以简单地更新tag啦。

注意不能再翻转的时候

#include<cstdio>
#include<algorithm>
#include<string.h>
#include<iostream>
using namespace std;
#define MAX 5000+9 int n, m;
int a[MAX];
int cf[MAX],is; void check(int k) {
int tag = 0;
for(int i = 1; i <= n; i++) {
tag += cf[i];
if((a[i]+tag) % 2 == 0) {
if(i+k-1 > n) {
m = MAX;
return ;
}
tag++;
cf[i+k]--;
m++;
}
}
} int main() {
scanf("%d",&n);
char c;
for(int i = 1; i <= n; i++) {
cin>>c;
if(c == 'F') a[i] = 1;//正
else a[i] = 0, is = 1;
}
if(is == 0) {
printf("1 0");
return 0;
}
int ansm = MAX, ansk;
for(int k = 1; k <= n; k++) {
memset(cf, 0, sizeof(cf));
check(k);
if(ansm > m) {
ansm = m;
ansk = k;
}
m = 0;
}
printf("%d %d",ansk, ansm);
}

luoguP2882Face The Right Way的更多相关文章

随机推荐

  1. Pwnable-fd

    打开Ubuntu输入ssh fd@pwnable.kr -p2222,连接之后输入密码guest 之后就是ls -l看看里面的文件和权限,fd.fd.c.flag 看看fd.c的源码 #include ...

  2. day3_7.1

    1.python的注释 python中为了使代码更容易被人看懂,提高团队开发效率,可使用注释.代码中的注释不加入编译中. 注释有单行注释,如 #这是一段注释 和多行注释: ''' 这是一行注释 ''' ...

  3. [C10] 异常检测(Anomaly Detection)

    异常检测(Anomaly Detection) 问题的动机 (Problem Motivation) 异常检测(Anomaly detection)问题是机器学习算法中的一个常见应用.这种算法的有趣之 ...

  4. C++ 模板特化、偏特化测试程序

    #include <iostream> // 偏特化的模板不会自己添加构造函数 ctor 和 析构函数 dtor #if 1 // P1 template <typename T1, ...

  5. 牛客小白月赛18 Forsaken喜欢数论

    牛客小白月赛18 Forsaken喜欢数论 题目传送门直接点标题 ​ Forsaken有一个有趣的数论函数.对于任意一个数xxx,f(x)f(x)f(x)会返回xxx的最小质因子.如果这个数没有最小质 ...

  6. 20191004 「HZOJ NOIP2019 Round #9」20191004模拟

    综述 第一次 rk1 ,激动. 题目是 COCI 18/19 Round #1 的三至五题. 得分 \(100+100+20\) \(\mathrm{cipele}\) 问题描述 HZOJ1313 题 ...

  7. luoguP2178 [NOI2015]品酒大会(后缀自动机)

    题意 承接上篇题解 考虑两个后缀的\(lcp\)是什么,是将串反着插入后缀自动机后两个前缀(终止节点)的\(lca\)!!!于是可以在parent tree上DP了. 比后缀数组又简单又好写跑的还快. ...

  8. <String> 179 ,6, 168

    179. Largest Number 冒泡排序,每一轮都把最小的数字选出放在最后. class Solution { public String largestNumber(int[] nums) ...

  9. DRF--验证器

    前戏 在之前我们对前端妹子传来的数据进行校验,使用的是序列化类来进行校验的,但这里面往往满足不了我们的需求,更多的时候我们希望自己定义校验规则.这里介绍三种自定义校验的方式.分别是单一字段校验,多个字 ...

  10. Nginx企业级优化

    Nginx企业级优化 一.隐藏版本号信息 安装软件前修改,源码包中的版本信息 #切换到源码包目录[root@localhost ~]# cd /usr/src/nginx-1.15.9/[root@l ...