Sum
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1490 Accepted Submission(s): 758
Problem 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 .
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
Source
思路:将每个数的f(x)-x存到新的数组中,求其中的最大连续字段和即可。
# include <bits/stdc++.h>
# define f(x) (1890*x+143)%10007
using namespace std;
int main()
{
int n, a, b, imin, imax, sum, sum2;
while(~scanf("%d",&n))
{
imin = sum = imax = sum2 = 0;
while(n--)
{
scanf("%d",&a);
b = f(a) - a;
sum += a;
sum2 += b;
imax = max(imax, sum2-imin);
imin = min(imin, sum2);
}
printf("%d\n",sum+imax);
}
return 0;
}
下面是idealism_xxm的dp代码:
#include <cstdio>
#include <algorithm>
using namespace std;
int n,num,i,dp[2][3];//dp[i&1][0]表示一直未进入置换区间,dp[i&1][1]表示当前处于置换区间,dp[i&1][2]表示当前已出置换区间(前面已经进入过了)
inline int f() {
return (1890*num+143)%10007;
}
int main() {
while(1==scanf("%d",&n)) {
dp[0][0]=dp[0][1]=dp[0][2]=0;
for(i=1;i<=n;++i) {
scanf("%d",&num);
dp[i&1][0]=dp[(i-1)&1][0]+num;
dp[i&1][1]=max(dp[(i-1)&1][0],dp[(i-1)&1][1])+f();
dp[i&1][2]=max(dp[(i-1)&1][1],dp[(i-1)&1][2])+num;
}
printf("%d\n",max(dp[n&1][0],max(dp[n&1][1],dp[n&1][2])));
}
return 0;
}