【郑轻oj】1837-LT说我不服(最大子序列的和)(思维)

点击打开题目

1837: LT说我不服

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 53   Solved: 12

Submit Status Web Board

Description

对于上一道题目LT不服,表示那么简单的题目不屑于去做,所以我们决定加大一下题目的难度,下面是我们LT出的题目:
假如给你一个由n个数组成的序列A1, A2, A3, A4 …… An。你可以选择任意一个大小的区间,将其中的每一个数x变成(x*1888+101)%14507。
求这n个数的最大和可能是多少。

Input

输入有多组数据
每组数据第一行输入一个整数n为序列元素个数。(1 <= n <= 100000)
第二行n个整数A1, A2, A3, A4 …… An。(0 <= Ai <= 10000)

Output

每组样例输出一行答案。

Sample Input

210000 999951 9999 1 9999 1

Sample Output

1999921989

HINT

 范围在int内

Source


第一次接触最小子序列的和的算法,提交两次,超时一次,第二次A了。

超时用了分冶的算法, 第二次的算法不好解释的通,我这里就自己写写试试吧(估计也只有自己懂了):从前往后逐项算和,不断地把最大的和保存入变量中,当和小于0时,便停止此轮的运算,从下一个数开始继续算和,直到结束。为什么可以这么算呢?根据个人的理解,既然每逢负数就从下一项开始重新计算,那么后面的最优解肯定是不包括前面的,而前面的最优解已经保存入变量中,如此筛选出被每个负数分开的子序列的和,最优解也一次次的更新,并不会漏解(感觉跟没说一样)。


代码如下:

#include <stdio.h>
int main()
{
	int u;
	int a[100022],b[100022];
	int max,tsum;
	while (~scanf ("%d",&u))
	{
		for (int i=1;i<=u;i++)
		{
			scanf ("%d",&a[i]);
			b[i]=(a[i]*1888+101)%14507;
			b[i]=b[i]-a[i];
		}
		max=0;
		tsum=0;
		for (int i=1;i<=u;i++)
		{
			tsum+=b[i];
			if (tsum>max)
				max=tsum;
			if (tsum<0)
			{
				tsum=0;
				continue;
			}
		}
		int cot=0;
		for (int i=1;i<=u;i++)
		{
			cot+=a[i];
		}
		cot+=max;
		printf ("%d\n",cot);
	}
	return 0;
}

嗯挺短的!算法很重要!





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值