poj2018

题意:在所有长度大于等于m的区间中找一个平均值最大的,输出平均数。

分析:动态规划,

f[i]表示以i结尾的最大平均数区间的数字总和。

num[i]表示f[i]对应的数字数量。

则有

f[i] = sum[i] - sum[i - m];
num[i] = m;

或者

f[i] = f[i - 1] + cow[i];
num[i] = num[i - 1] + 1;

意思是要么直接取长为m的区间,要么取以其前一个结尾的最大平均值区间,把当前数字加入其中。

View Code
#include < iostream >
#include
< cstdio >
#include
< cstdlib >
#include
< cstring >
using namespace std;

#define maxn 100005

int n, m;
int cow[maxn], sum[maxn], num[maxn], f[maxn];

int main()
{
// freopen("t.txt", "r", stdin);
scanf( " %d%d " , & n, & m);
for ( int i = 1 ; i <= n; i ++ )
scanf(
" %d " , & cow[i]);
sum[
0 ] = 0 ;
for ( int i = 1 ; i <= n; i ++ )
sum[i]
= sum[i - 1 ] + cow[i];
for ( int i = m; i <= n; i ++ )
{
if (i - 1 < m || (sum[i] - sum[i - m]) * 1.0 / m > (f[i - 1 ] + cow[i]) * 1.0 / (num[i - 1 ] + 1 ))
{
f[i]
= sum[i] - sum[i - m];
num[i]
= m;
}
else
{
f[i]
= f[i - 1 ] + cow[i];
num[i]
= num[i - 1 ] + 1 ;
}
}
int ans = - 1 ;
for ( int i = m; i <= n; i ++ )
if (ans < f[i] * 1000 / num[i])
ans
= f[i] * 1000 / num[i];
printf(
" %d\n " , ans);
return 0 ;
}

你可能感兴趣的:(poj)