http://acm.fzu.edu.cn/problem.php?pid=2168
題目大意:
給定n個數和m,要求從n個數中選擇連續的m個,使得a[i]*1+a[i+1]*2+……a[i+m]*m最大
思路:
常規思路是以每個數開始,枚舉m個,但是這樣會TLE。
可以有O(n)的算法。
例如樣例的
n=5 m=3
五個數分別爲
2 1 3 1 4
有三種連續的三個數
2 * 1 + 1 * 2 + 3* 3 = 13
1 * 1 + 3 * 2 + 1 * 3= 10
3 * 1 + 1 * 2 + 4 * 3 = 17
設sum[i]爲到i的m個數的和,dp[i]爲以i結束的m個數的乘積值。
則相鄰兩組間有關係,dp[i] =dp[i-1]-sum[i-1] + m*a[i] ;
例如 第第二組的那個 dp[4 ]= dp[3]- sum[3] + 3 * 1 = 13-6+3*1=10
#include<cstdio>
const int MAXN=1000000+10;
int sum[MAXN],dp[MAXN],a[MAXN];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
sum[0]=0;
dp[m]=0;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
sum[i]=sum[i-1]+a[i];
dp[m]+=a[i]*i;
}
int ans=dp[m];
for(int i=m+1;i<=n;i++)
{
dp[i]=dp[i-1]-sum[i-1];
dp[i]=dp[i]+m*a[i];
sum[i]=sum[i-1]+a[i]-a[i-m];
if(ans<dp[i])
ans=dp[i];
}
printf("%d\n",ans);
}
return 0;
}