1. 程式人生 > >Best Cow Fences POJ

Best Cow Fences POJ

思路:直接寫出表示式 sum[i]-sum[j]/(i-j)

發現是個斜率的式子,所以考慮直接用斜率優化來做。

其餘部分根簡單,只要注意要維護一個長度不超過k的區間,在入隊的時候需要處理成 i-k+1的形式。

程式碼:

#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn=1e5+6;
int n,m;
int a[maxn];
int sum[maxn];
double dp[maxn];
int q[maxn];
double solve(int i,int j)
{
    return 1.0*(sum[i]-sum[j])/(i-j);
}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    scanf("%d%d",&n,&m);
    sum[0]=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        sum[i]=sum[i-1]+a[i];
    }
    int head,tail;
    head=tail=0;
    double ans=0;
    for(int i=m;i<=n;i++)
    {
        while(head<tail&&solve(i,q[head])<solve(i,q[head+1]))
        {
            head++;
        }
        dp[i]=1.0*(sum[i]-sum[q[head]])/(i-q[head]);
        ans=max(ans,dp[i]);
        int k=i-m+1;//為了維護最多有m個
        while(head<tail&&solve(q[tail],q[tail-1])>solve(k,q[tail]))
        {
            tail--;
        }
        q[++tail]=k;
    }
    printf("%d\n",int(ans*1000));
    return 0;
}