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)的主要内容,如果未能解决你的问题,请参考以下文章