luoguP2418 yyy loves OI IV

https://www.luogu.org/problemnew/show/P2418

暴力 DP 做这题只有 30 分

考虑用线段树优化这个 DP

先处理一下整个房间都膜拜一个人的情况,然后将 1 的当成 -1, 2 当成 1,处理前缀和,可以发现对于前缀和为 x 的情况,只能从前缀和为 [x - k, x + k] 的地方转移过来,用线段树维护 DP 数组的最小值就行了

#include <bits/stdc++.h>
using namespace std;

const int N = 500000 + 10;

int minn[N << 3], a[N], s[N], f[N];
int n, k, last;

void change(int u, int l, int r, int x, int y) {
    minn[u] = min(minn[u], y);
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(mid >= x) change(u << 1, l, mid, x, y);
    else change(u << 1 | 1, mid + 1, r, x, y);
}

int Q;

void query(int u, int l, int r, int L, int R) {
    if(l <= L && R <= r) {
        Q = min(Q, minn[u]);
        return;
    }
    int mid = (L + R) >> 1;
    if(mid >= l) query(u << 1, l, r, L, mid);
    if(mid + 1 <= r) query(u << 1 | 1, l, r, mid + 1, R);
}

int main() {
    memset(minn, 0x3f, sizeof(minn));
    cin >> n >> k; s[0] = N;
    for(int i = 1; i <= n; i++) {
        int t; scanf("%d", &t);
        if(t == 1) a[i] = -1;
        else a[i] = 1;
        s[i] = s[i - 1] + a[i];
    }
    change(1, 1, n + k + N, N, 0);
    for(int i = 1; i <= n; i++) {
        if(a[i] != a[i - 1]) last = f[i - 1];
        else last = min(last, f[i - 1]);
        f[i] = last + 1;
        Q = INT_MAX;
        query(1, s[i] - k, s[i] + k, 1, n + k + N);
        f[i] = min(f[i], Q + 1);
        change(1, 1, n + k + N, s[i], f[i]);
    }
    cout << f[n] << endl;
    return 0;
}

原文地址:https://www.cnblogs.com/LJC00118/p/9607239.html

时间: 2024-08-07 06:28:12

luoguP2418 yyy loves OI IV的相关文章

[洛谷1580]yyy loves Easter_Egg I

题目背景 Soha的出题效率着实让人大吃一惊.OI,数学,化学的题目都出好了,物理的题还没有一道.于是,Huntfire,absi2011,lanlan对soha进行轮番炸,准备炸到soha出来,不料,人群中冲出了个kkksc03…… 题目描述 yyy loves OI(Huntfire),yyy loves Maths(lanlan),yyy loves Chemistry(absi2011)对yyy loves Physics(soha)进行轮番炸,轰炸按照顺序进行,顺序为Huntfire,

yyy loves Easter_Egg I(恶心的字符串模拟)

题目背景 Soha的出题效率着实让人大吃一惊.OI,数学,化学的题目都出好了,物理的题还没有一道.于是,Huntfire,absi2011,redbag对soha进行轮番炸,准备炸到soha出来,不料,人群中冲出了个kkksc03…… 题目描述 yyy loves OI(Huntfire),yyy loves Maths(redbag),yyy loves Chemistry(absi2011)对yyy loves Physics(soha)进行轮番炸,轰炸按照顺序进行,顺序为Huntfire,

[洛谷P1580]yyy loves Easter_Egg I

题目大意:很多人@一个人,如果那个人忍不住说话了,就轰炸成功,如果那个人没说话或者别的人没有@他或@很多个人,则轰炸失败.(具体见原题) 解题思路:字符串处理,好好用sscanf即可(细节见代码). C++ Code: #include<cstring> #include<algorithm> #include<cstdio> char s[1050],zha[1050],shuohua[1050],At[1050]; int q=1; int main(){ fget

洛谷——P2393 yyy loves Maths II

P2393 yyy loves Maths II 题目背景 上次蒟蒻redbag可把yyy气坏了,yyy说他只是小学生,蒟蒻redbag这次不坑他了. 题目描述 redbag给了yyy很多个数,要yyy计算这些数的和.必须要快,redbag只给了yyy1秒的时间!!! 输入输出格式 输入格式: 一行,很多个数 输出格式: 一行,一个实数(四舍五入精确到5位小数),表示这些数的和. 输入输出样例 输入样例#1: 复制 1 输出样例#1: 复制 1.00000 说明 [数据规模] 对于100%的数据

洛谷 P2393 yyy loves Maths II

P2393 yyy loves Maths II 题目背景 上次蒟蒻redbag可把yyy气坏了,yyy说他只是小学生,蒟蒻redbag这次不坑他了. 题目描述 redbag给了yyy很多个数,要yyy计算这些数的和.必须要快,redbag只给了yyy1秒的时间!!! 输入输出格式 输入格式: 一行,很多个数 输出格式: 一行,一个实数(四舍五入精确到5位小数),表示这些数的和. 输入输出样例 输入样例#1: 复制 1 输出样例#1: 复制 1.00000 说明 [数据规模] 对于100%的数据

[P1580] yyy loves Easter_Egg I

Link: P1580 传送门 Solution: 拿来练练字符串的读入: 1.$gets()$相当于$c++$中的$getline()$,但返回值为指针!(无数据时为NULL) (都读入换行符,并将其舍弃) 2.$sscanf(起始指针,.....,......)$可以实现从另一个字符串读入 3.$strcmp$和$memcmp$都是相同时返回值为0 4.$count(begin,end,value)$能实现各个容器中的个数查找 5.$strstr(s1,s2)$能查找$s1$中第一个$s2$

$题解 P2394 【yyy loves Chemistry I】$

$ P2394 ?yyy ?loves ? Chemistry ?I$ 感觉这道题没这么难啊?本蒟蒻还是很疑惑,为什么评分为普及+/提高呢? 好了,废话不多说,一起愉快地做题吧! \[First:\text{输入}\] 我相信,第一次做题的时候,大多数的人都会这么输入 scanf("%Lf",&a); 但这么输入是错误的,为什么呢?因为\(a\)的精度你无法确定,而long double的精度只有\(18-19\)位. 那怎么办呢?别急别急,喝口茶慢慢说,好在scanf可以强制

luogu P2397 yyy loves Maths VI (mode)

题目背景 自动上次redbag用加法好好的刁难过了yyy同学以后,yyy十分愤怒.他还击给了redbag一题,但是这题他惊讶的发现自己居然也不会,所以只好找你 题目描述 [h1]udp2:第一题因为语言性质问题,比赛结束后将所有c/c++的程序的内存调为2.2mb后重测.[/h1] 他让redbag找众数 他还特意表示,这个众数出现次数超过了一半 一共n个数,而且保证有 n<=2000000 而且每个数<2^31-1 输入输出格式 输入格式: 第一行一个整数n 第二行n个整数 输出格式: 一行

luogu2393 yyy loves Maths II

使用long double #include <iostream> #include <cstdio> using namespace std; long double ans=0.0, xx; int main(){ while(scanf("%Lf", &xx)!=EOF) ans = ans + xx * 1000000; printf("%.5Lf", ans/1000000); return 0; } 原文地址:https: