562. 壁画 - AcWing题库
Thanh 想在一面被均分为 N 段的墙上画一幅精美的壁画。
每段墙面都有一个美观评分,这表示它的美观程度(如果它的上面有画的话)。
不幸的是,由于洪水泛滥,墙体开始崩溃,所以他需要加快他的作画进度!
每天 Thanh 可以绘制一段墙体。
在第一天,他可以自由的选择任意一段墙面进行绘制。
在接下来的每一天,他只能选择与绘制完成的墙面相邻的墙段进行作画,因为他不想分开壁画。
在每天结束时,一段未被涂颜料的墙将被摧毁(Thanh 使用的是防水涂料,因此涂漆的部分不能被破坏),且被毁掉的墙段一定只与一段还未被毁掉的墙面相邻。
Thanh 的壁画的总体美观程度将等于他作画的所有墙段的美观评分的总和。
Thanh想要保证,无论墙壁是如何被摧毁的,他都可以达到至少 B 的美观总分。
请问他能够保证达到的美观总分 B 的最大值是多少。
输入格式
第一行包含整数 T,表示共有 T 组测试数据。
每组数据的第一行包含整数 N。
第二行包含一个长度为 N的字符串,字符串由数字 0∼9 构成,第 i 个字符表示第 i 段墙面被上色后能达到的美观评分。
输出格式
每组数据输出一个结果,每个结果占一行。
结果表示为
Case #x: y
,其中 x为组别编号(从 1 开始),y 为 Thanh 可以保证达到的美观评分的最大值。数据范围
1≤T≤100
存在一个测试点N=5∗106,其他测试点均满足2≤N≤100输入样例:
4 4 1332 4 9583 3 616 10 1029384756
输出样例:
Case #1: 6 Case #2: 14 Case #3: 7 Case #4: 31
样例解释
在第一个样例中,无论墙壁如何被破坏,Thanh都可以获得 6 分的美观总分。在第一天,他可以随便选一个美观评分3的墙段进行绘画。在一天结束时,第一部分或第四部分将被摧毁,但无论哪一部分都无关紧要。在第二天,他都可以在另一段美观评分 3 的墙段上作画。
在第二个样例中,Thanh 在第一天选择最左边的美观评分为 9 的墙段上作画。在第一天结束时唯一可以被毁掉的墙体是最右边的那段墙体,因为最左边的墙壁被涂上了颜料。在第二天,他可以选择在左数第二段评分为 5 的墙面上作画。然后右数第二段墙体被摧毁。请注意,在第二天,Thanh不能选择绘制第三段墙面,因为它不与任何其他作画墙面相邻。这样可以获得 14 分的美观总分。
墙只能从两头坏,因为毁掉的墙就和两段未被毁掉的墙面相邻了,题目要求被毁掉的墙段一定只与一段还未被毁掉的墙面相邻,且只能选择与绘制完成的墙面相邻的墙段进行作画,所以
题目等价于求长度为 ⌈n/2⌉的连续子数组的最大和。
所以取得[n/2]的区间大小,向上取整公式为:(a+x-1)/x,然后枚举结束点,减去区间长度得到起始点,然后通过前缀和直接获得区间大小然后取最大值就行了
AC code:
#include<bits/stdc++.h> using namespace std; int arr[5000010]; int main() {int t;cin >> t;for (int u = 1; u <= t; u++) {int n;int ans = -1;cin >> n;arr[0] = 0;string s;for (int i = 1; i <= n; i++) {char r;cin >> r;arr[i] = r - '0';arr[i] += arr[i - 1];}int x = (n + 1) / 2;for (int i = x; i <= n; i++) {int l = i;int r = l + x -1;int res = arr[i] - arr[i-x];ans = max(ans, res);}printf("Case #%d: %d\n", u, ans);} }