Educational Codeforces Round 123 (Rated for Div. 2)
Posted yeah17981
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 123 (Rated for Div. 2)相关的知识,希望对你有一定的参考价值。
A:给6个字符串其中rgb和RGB各一个,分别代表钥匙和门,人从左往右走能不能走到尽头
题解:模拟,然后wa了,然后发现是if的时候R写成B了,傻逼玩意儿
B:构造序列,满足用到1-n的每个元素各一次且序列满足ai+ ai+1 !=ai+2(斐波那契)
题解:以9和8为例
8:8 1 / 7 2 / 6 3 / 5 4,两两一组,和为9,且大的数字在前,每组间隔的位置和为n(此时因为最大数n前面必为另外一组,和为n+1),头尾相连,相邻和为2*n+n/2,从中间切一刀,必然满足
9:9/8 1 / 7 2 / 6 3 / 5 4,最大数字放首位,不动,后面按照n-1处理,此时还差一个序列,n和n-1调换,后面不变,输出即可
另外的构造方法:以6为例,654321,将1往前提即可(好的我承认我是傻逼)
C:给一个数组,和一个数字x,f(k)表示给k个不同的位置+ x,加完后子串和最大,求k从0-n时子串和最大值
题解:对于一个k,和最大的结果的长度a可能比k大也可能比k小,如果比k小,结果就是sum(r-l+1)+(r-l+1)*x,比k大就是sum(r-l+1)+k*x
f1(i)表示长度为i的段,sum(i)+i*x的最大值
f2(i)表示长度为i的段,sum(i)+k*x的最大值
取k为j,则结果应该为f1从1-j的最大值,f2从j到n的最大值,的最大值
因此分别求一个前缀最大值和一个后缀最大值
而sum通过暴力来求出
#include<iostream>
using namespace std;
const int N = 5005;
int sum[N];
int a[N];
int f[N];
int q[N], h[N];
int main()
int _, n, x;
cin >> _;
while (_--)
cin >> n >> x;
memset(sum, 0, sizeof(sum));
memset(a, 0, sizeof(a));
for (int i = 1; i <= n + 5; i++)
f[i] = -0x7fffffff;//有的傻逼因为这里多写了个fwa了
h[i] = -0x7fffffff;//因为结果可能为负数,所以初始化的时候应该为最小值而不是0;
memset(q, 0, sizeof(q));
for (int i = 1; i <= n; i++)
cin >> a[i];//输入
for (int i = 1; i <= n; i++)
sum[i] = sum[i - 1] + a[i];//前缀和,用来求线段和
for (int i = 1; i <= n; i++)
for (int j = 1; j + i - 1 <= n; j++)
f[j] = max(f[j], sum[j + i - 1] - sum[i - 1]);//求长度为j的线段最大值
for (int i = 1; i <= n; i++)
q[i] = max(q[i - 1], f[i] + i * x);//f1,前缀最大值
for (int i = n; i >= 0; i--)
h[i] = max(h[i + 1], f[i]);//f2,后缀最大值,少一个+k*x
for (int i = 0; i <= n; i++)
cout << max(h[i] + i * x, q[i]) << " ";
cout << "\\n";
以上是关于Educational Codeforces Round 123 (Rated for Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章