SGU 549 - Dumbbells

来源:互联网 发布:qq音乐网络代理 编辑:程序博客网 时间:2024/06/06 17:40
A sports shop has n dumbbells in store. Each of them is characterised by its mass mi and cost ci. Recently the shop manager faced the following non-trivial problem. He has to find the maximum number of sports sets that satisfy the following requirements:

  • each set must contain exactly k dumbbells;
  • each set must have dumbbells of k distinct masses;
  • for each pair of sets the masses of dumbbells must coincide , that is, the masses in the sets must be equal as .


The manager's task is to make the maximum number of such sets. If there are several ways to make the maximum possible number of sets, he should choose the one that has the maximum total cost of dumbbells that are contained in the chosen sets. Note that the primary goal is to maximize the number of sets and maximization of the total cost is the secondary goal.

Input

The first line of the input contains integers n and k (1 ≤ n,k ≤ 4000). Next n lines contain descriptions of the dumbbells, one per line. Each description consists of a pair of integers mici (1 ≤ mi,ci ≤ 4000), mi is the mass of the i-th dumbbell, and ci is its cost.

Output

In the only output line print two integers — t and s, where t is the maximum number of sets, and s is the maximum total cost of dumbbells in t choosen sets. If the manager can't make at least one set, print a pair of zeroes.

Sample Input

Example(s)
sample input
sample output
7 216 14 616 77 10032 94 632 1
2 22

Hint

In the first sample the manager should make two sets. One of the possible solutions is as follows: the first set contains the second and the seventh dumbbells, the second set contains the fifth and the sixth dumbbells.

In the second sample the manager can make only one set. It consists of the third and the fourth dumbbells.

题意:  给每个杠铃的质量和价值 .组成一套设备,每套设备要求每个杠铃质量不同,由K个杠铃组成.每套设备的杠铃要求质量相同.求能组成多少套,和总的价值.

将所有的物品按照重量分类,然后按照每类物品的数量的多少排序,对于前k个类,每次从每个类中取一个,就可以组成重量相等的具有k个物品的set,最多可以组成的set的数目是num[k].

对于每类物品,总的来说都要取num[k]个,同时考虑使总费用最大,所以要对每类物品按照费用从大到小排序,然后就可以取前面的num[k]个.

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<queue>#include<iostream>#include<algorithm>using namespace std ;int sum[5000],num[5000];struct node{int x,y;             //杠铃的质量,和价值}s[5000]; int cmp(node a, node b )          //排序{if(num[a.x]!=num[b.x])       //数量不相等的按数量从大到小排序{return num[a.x] > num[b.x]; }return a.x==b.x ? a.y>b.y : a.x > b.x ;  //数量相等的同时质量也相等的按价值从大到小排,}                                 //数量相等的同时质量不相等的按质量从大到小排,int main(){int  n , k , i , j ,len , cost , cnt ;while(~scanf("%d%d",&n,&k)){memset(num,0,sizeof(num));     for( i = 0 ; i < n ; i++){scanf("%d%d",&s[i].x,&s[i].y);num[s[i].x]++;                 //质量为s[i].x的数量为num[s[i].x .}sort(s,s+n,cmp);                      //按规则排序for ( i = 1 , j = 1  ; i<n ; i++){if(s[i].x!=s[i-1].x)      //如果质量部相等.{j++ ;             //j为质量不同的杠铃种数if(j > k && num[s[i].x]<num[s[i-1].x])   //注意,有多个杠铃数量相等的时候,j是要比k大的   break ;}}len = num[s[i-1].x] ;         //最小的杠铃数量,也是能组成的设备套数if(j<k)                       //杠铃种数小于k , 无解{printf("0 0\n");continue ;} for( i =  0 ,cnt = 0; num[s[i].x]>=len ; i += num[s[i].x]) // i += num[s[i].x] ,是跳到下一种杠铃.{sum[cnt]=0;                  //每种杠铃的价值总和for( j = 0 ; j < len ; j++)    sum[cnt] += s[i+j].y ; cnt++;                            //因为会有多个相等的杠铃种类,所以cnt可能会比k大} sort(sum,sum+cnt);      //从小到大排序,所以下面的要从后面开始加,才保证价值最大for( i = cnt-1 , cost = 0 ; i>=0 && i >= cnt-k  ; i--)  //注意i >= cnt-k   ,因为,cnt>=k ;     cost += sum[i] ; printf("%d %d\n",len,cost);     } return 0;} 


原创粉丝点击