问题:
马克是一名本科生,他对轮换感兴趣。马克希望赢得一个传送带比赛正在进行。在比赛中,有一条传送带,可以表示为1xN块的条带。每个块上都写有一个数字。皮带保持旋转,每次旋转后,每个程序段都会向左移动,第一个程序段将转到最后位置。
传送带附近有一个开关可以阻止皮带。每个参与者都有一次机会阻止腰带,他的PMEAN将被计算出来。
PMEAN使用皮带停止时的顺序计算。具有最高PMEAN的参与者是赢家。可以有多个获胜者。
马克希望成为赢家之一。他应该尝试哪种PMEAN来保证他成为赢家。
PMEAN=∑i=1ni×a[i]
其中a表示传送带停止时的配置。索引从1开始。
输入格式
First line contains N denoting the number of elements on the belt.
Second line contains N space separated integers.
输出格式
Output the required PMEAN
约束
1 ≤ N ≤ 10^6
-10^9 ≤ each number ≤ 10^9
对于任何旋转,PMEAN将始终位于64位有符号整数的范围内。
示例输入
3
20 30 10
示例输出
140
解释
顶部的数字可以用这些方式书写。
皮带上的初始数字,`
20 30 10
PMEAN = 1x20 + 2x30 + 3x10 = 110`
首次轮换后,
30 10 20
PMEAN = 1x30 + 2x10 + 3x20 = 110
第二次轮换后,
10 20 30
PMEAN = 1x10 + 2x20 + 3x30 = 140
因此最大可能值为140。
代码:
#include <stdio.h>
int main() {
int n,i;
scanf("%d",&n);
int b[n],a[n],k,ans,temp;
int *sum = calloc(n,sizeof(int)) ;
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(k=0;k<n;k++){
for(i=0;i<n;i++){
b[i] = a[(i+k)%n];
sum[k]+= (i+1)*b[i];
}
if(ans<sum[k] || k==0){
ans = sum[k];
}
}
printf("%d",ans);
return 0;
}
代码很好,但执行时间太长。如何将其复杂度从N ^ 2降低到更低?
答案 0 :(得分:0)
经过一段时间的思考,我得到了答案:
#include <stdio.h>
int main() {
int n,i,k;
scanf("%d",&n);
long long int a[n],sum[n], ans, s=0,temp;
sum[0] =0;
for(i=0;i<n;i++){
scanf("%lld",&a[i]);
sum[0]+=(i+1)*a[i];
s+= a[i];
}
ans = sum[0];
for(k=1;k<n;k++){
temp = n*a[k-1];
sum[k]= sum[k-1] - s + temp;
if(ans<sum[k])
ans = sum[k];
}
printf("%lld",ans);
return 0;
}