hdu 5586 Sum 最大子段和
Sum
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://acm.hdu.edu.cn/showproblem.php?pid=5586
Description
There is a number sequence A1,A2....An,you can select a interval [l,r] or not,all the numbers Ai(l≤i≤r) will become f(Ai).f(x)=(1890x+143)mod10007.After that,the sum of n numbers should be as much as possible.What is the maximum sum?
Input
There are multiple test cases.
First line of each case contains a single integer n.(1≤n≤105)
Next line contains n integers A1,A2....An.(0≤Ai≤104)
It's guaranteed that ∑n≤106.
Output
For each test case,output the answer in a line.
Sample Input
2 10000 9999 5 1 9999 1 9999 1
Sample Output
19999 22033
HINT
题意
给你n个数,你可以使得一个区间的数由a[i]变成b[i],b[i] = (1890*a[i]+143)mod10007,问你答案最大为多少
题解:
将b[i]减去a[i],然后跑一个最大子段和就好了
可以dp,也可以尺取法
代码:
#include<iostream> #include<stdio.h> #include<cstring> using namespace std; #define maxn 100005 long long a[maxn]; long long b[maxn]; long long sumb[maxn]; long long get(long long x) { return (1890*x+143)%10007; } int main() { int n; while(scanf("%d",&n)!=EOF) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); long long sum = 0; for(int i=1;i<=n;i++) { scanf("%I64d",&a[i]); sum += a[i]; } for(int i=1;i<=n;i++) { b[i]=get(a[i])-a[i]; } long long Tmp = 0 , tmp = 0; for(int i = 1 ; i <= n ; ++ i) { if(tmp + b[i] < 0) { Tmp = max(Tmp , b[i]); Tmp = max(Tmp , tmp); tmp = 0; } else { tmp += b[i]; Tmp = max(Tmp,tmp); } } printf("%I64d\n",sum+Tmp); } }