网站建设实训周记,上海网站制作推广,网站出现建设中,什么网站做二维码比较好CF 1000B
link 题意: 自习室内有一个智能灯。
在 0 时刻,管理员会将打开电闸,并将灯点亮。
在 M 时刻,管理员会直接拉下电闸,此时,如果灯处于点亮状态,则会因为断电而熄灭。
在 0∼M 之间有 n 个不同时…
CF 1000B
link
题意:
自习室内有一个智能灯。
在 0 时刻,管理员会将打开电闸,并将灯点亮。
在 M 时刻,管理员会直接拉下电闸,此时,如果灯处于点亮状态,则会因为断电而熄灭。
在 0∼M 之间有 n 个不同时刻,不妨用 a1,a2,…,an 表示,其中 0<a1<a2<…<an<M。
在这 n 个时刻中的每个时刻,管理员都会拨动一次智能灯的开关,使灯的状态切换(亮变灭、灭变亮)。
现在,你可以最多额外指定一个时刻(也可以不指定),让管理员在此时刻也拨动开关一次。注意选定的时刻不能与 a1,a2,…,an 相等。
你的目的是让亮灯的总时长尽可能长。
输出这个最大亮灯总时长。
题解:
n + 1 个点,n个时间段,本身是奇数区间亮灯偶数区间灭灯,但是当选取任意一个区间操作后,都会使得这个操作后面变成偶数区间亮,奇数区间灭,因此,可以枚举每一个区间操作后的亮灯总长,取一个最大值即可。
Code
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <set>
#include <queue>
#include <vector>
#include <map>
#include <unordered_map>
#include <cmath>
#include <stack>
#include <iomanip>
#define x first
#define y second
#define eps 1e-7
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
const int N = 2e5 + 10, M = 30010, INF = 0x3f3f3f3f, P = 131, mod = 1e9 + 7;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int n, m;
int a[N], f[N];
int s1[N], s2[N];
int main () {cin.tie(nullptr)->sync_with_stdio(false);cin >> n >> m;for (int i = 1; i <= n; i ++ ) cin >> a[i];a[++ n] = m;s1[n] = s2[n] = 0;for (int i = n - 1; i >= 0; i -- ) { // 因为区间从(a1 - a0)开始,所以逆序前缀和也可以 s1[i] = s1[i + 1], s2[i] = s2[i + 1];if (i % 2 == 0) s1[i] += a[i + 1] - a[i]; // 奇区间前缀和 枚举的是区间长度 因此前缀和的是区间长度 else s2[i] += a[i + 1] - a[i]; // 偶区间前缀和 }int res = s1[0]; // 一个不选的情况,也就是所有偶数区间的和 for (int i = 0; i < n; i ++ ) {int t = a[i + 1] - a[i]; // 无论选奇数还是偶数操作,最终选的这个区间贪心下来长度贡献都是 t - 1 if (t == 1) continue;res = max(res, s1[0] - s1[i] + t - 1 + s2[i + 1]); // 分为,操作区间前面的奇数区间,操作区间,操作区间后面的偶数区间 }cout << res << endl; return 0;
}