首页 > ACM题库 > HDU-杭电 > HDU 3045-Picnic Cows-动态规划-[解题报告]HOJ
2014
02-27

HDU 3045-Picnic Cows-动态规划-[解题报告]HOJ

Picnic Cows

问题描述 :

It’s summer vocation now. After tedious milking, cows are tired and wish to take a holiday. So Farmer Carolina considers having a picnic beside the river. But there is a problem, not all the cows consider it’s a good idea! Some cows like to swim in West Lake, some prefer to have a dinner in Shangri-la ,and others want to do something different. But in order to manage expediently, Carolina coerces all cows to have a picnic!
Farmer Carolina takes her N (1<N≤400000) cows to the destination, but she finds every cow’s degree of interest in this activity is so different that they all loss their interests. So she has to group them to different teams to make sure that every cow can go to a satisfied team. Considering about the security, she demands that there must be no less than T(1<T≤N)cows in every team. As every cow has its own interest degree of this picnic, we measure this interest degree’s unit as “Moo~”. Cows in the same team should reduce their Moo~ to the one who has the lowest Moo~ in this team――It’s not a democratical action! So Carolina wishes to minimize the TOTAL reduced Moo~s and groups N cows into several teams.
For example, Carolina has 7 cows to picnic and their Moo~ are ‘8 5 6 2 1 7 6’ and at least 3 cows in every team. So the best solution is that cow No.2,4,5 in a team (reduce (2-1)+(5-1) Moo~)and cow No.1,3,6,7 in a team (reduce ((7-6)+(8-6)) Moo~),the answer is 8.

输入:

The input contains multiple cases.
For each test case, the first line has two integer N, T indicates the number of cows and amount of Safe-base line.
Following n numbers, describe the Moo~ of N cows , 1st is cow 1 , 2nd is cow 2, and so on.

输出:

The input contains multiple cases.
For each test case, the first line has two integer N, T indicates the number of cows and amount of Safe-base line.
Following n numbers, describe the Moo~ of N cows , 1st is cow 1 , 2nd is cow 2, and so on.

样例输入:

7 3
8 5 6 2 1 7 6

样例输出:

8

 思路:

        首先排序

        状态转移方程: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;
}

     

       

参考:http://blog.csdn.net/job_yi/article/details/9881119


  1. 其实国内大部分公司对算法都不够重视。特别是中小型公司老板根本都不懂技术,也不懂什么是算法,从而也不要求程序员懂什么算法,做程序从来不考虑性能问题,只要页面能显示出来就是好程序,这是国内的现状,很无奈。