[hdu][3045][Picnic Cows]

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3045

View Code
#include <stdio.h>

#include <string.h>

#include <math.h>

#include <algorithm>



#define ll __int64

#define clr(a,b) memset(a, b, sizeof(a))

using namespace std;



const int N = 500000+10;

const int M = 10000+10;

const int inf = 0x3f3f3f3f;



int m, n, l, r;

int q[N];

ll a[N], s[N], dp[N];



// dp[i] = min{dp[j]+sum[i]-sum[j]-(i-j)*a[j+1]}



void input()

{

    for (int i=1; i<=n; i++)

        scanf("%I64d", &a[i]);

    sort(a+1, a+n+1);

    a[0] = s[0] = dp[0] = 0;

    for (int i=1; i<=n; i++)

        s[i] = s[i-1] + a[i], dp[i] = 0;

}



bool super1(int k1, int k2, int k3, int i)

{

    return (dp[k3]-dp[k2]-(i-k3)*a[k3+1]+(i-k2)*a[k2+1])*(s[k2]-s[k1])

           <=(dp[k2]-dp[k1]-(i-k2)*a[k2+1]+(i-k1)*a[k1+1])*(s[k3]-s[k2]); // =很重要,,poj3709上没有这个WA了

}



bool super2(int k1, int k2, int i)

{

    return dp[k1]-s[k1]-(i-k1)*a[k1+1]>=dp[k2]-s[k2]-(i-k2)*a[k2+1];

}



int main()

{

    //freopen("D:/a.txt", "r", stdin);

    while (~scanf("%d%d", &n, &m))

    {



        input();

        q[l=0] = 0, r=-1;

        for (int i=1; i<=n; i++)

        {

            if (i>=2*m)

            {

                int now = i-m;

                while (l<r && super1(q[r-1],q[r],now,i))r--;

                q[++r]=now;

            }

            while (l<r && super2(q[l],q[l+1],i))l++;

            int k = q[l];

            dp[i] = dp[k]+s[i]-s[k]-(i-k)*(a[k+1]);

        }

        printf("%I64d\n", dp[n]);

    }

    return 0;

}

你可能感兴趣的:(HDU)