HDU 3045 Picnic Cows【dp斜率优化】

 思路:

        首先排序

        状态转移方程:dp[i]=min{dp[j]+(sum[i]-sum[j])-a[j+1]*(i-j)}

        AC代码:

#include<stdio.h>
#include<stdlib.h>
#define N 400010
_int64 dp[N],sum[N],a[N];
int q[N];
int n,T;
int head,tail;
int cmp(const void *a,const void *b)
{
    return *(int *)a-*(int *)b;
}
_int64 getDP(int i,int j)
{
     return dp[j]+(sum[i]-sum[j])-a[j+1]*(i-j);
} 
_int64 getUP(int j,int k)
{
      return dp[j]-sum[j]+a[j+1]*j-(dp[k]-sum[k]+a[k+1]*k);
}
_int64 getDOWN(int j,int k)
{
      return  a[j+1]-a[k+1];
}
int main()
{
	int i,j;
	while(scanf("%d%d",&n,&T)!=-1)
	{
	    for(i=1;i<=n;i++)
			scanf("%d",&a[i]);
		qsort(a+1,n,sizeof(a[1]),cmp);
		sum[0]=0;
		for(i=1;i<=n;i++)
			sum[i]=sum[i-1]+a[i];
        dp[0]=0;
		head=tail=0;
		q[tail++]=0;
		for(i=1;i<=n;i++)
		{
		   while(head+1<tail&&getUP(q[head+1],q[head])<=i*getDOWN(q[head+1],q[head]))
			   head++;
		   dp[i]=getDP(i,q[head]);
		   j=i-T+1;
		   if(j<T)continue;
		   while(head+1<tail&&getUP(q[tail-1],q[tail-2])*getDOWN(j,q[tail-1])>=getUP(j,q[tail-1])*getDOWN(q[tail-1],q[tail-2]))
			   tail--;
		   q[tail++]=j;
		}
		printf("%I64d\n",dp[n]);
	}
    return 0;
}


     

       

你可能感兴趣的:(HDU 3045 Picnic Cows【dp斜率优化】)