元旦快到了,校學生會讓樂樂負責新年晚會的紀念品發放工作。爲使得參加晚會的同學所獲得的紀念品價值相對均衡,他要把購來的紀念品根據價格進行分組,但每 組最多只能包括兩件紀念品,並且每組紀念品的價格之和不能超過一個給定的整數。爲了保證在儘量短的時間內發完所有紀念品,樂樂希望分組的數目最少。
你的任務是寫一個程序,找出所有分組方案中分組數最少的一種,輸出最少的分組數目。
【輸入】
輸入文件group.in包含n+2行:
第1行包括一個整數w,爲每組紀念品價格之和的上限。
第2行爲一個整數n,表示購來的紀念品的總件數。
第3~n+2行每行包含一個正整數pi(5<=pi<=w),表示所對應紀念品的價格。
【輸出】
輸出文件group.out僅一行,包含一個整數,即最少的分組數目。
【輸入樣例】
100
9
90
20
20
30
50
60
70
80
90
【輸出樣例】
6
【限制】
50%的數據滿足:l<=n<=15
100%的數據滿足:1<=n<=30000,80<=w<=200
【分析】
貪心策略,先排序,可以用快排、堆排、插入排序、甚至桶排序,每次找到最小的價格Min和最大的價格Max,如果Max+Min>W,則有最大價格的那個物品單獨成一組,然後更新Max;如果Max+Min<=W,則把這兩件物品分為一組,然後更新Min和Max。
【參考程序】
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
int num[30001];
int Max=0,Min=0xfffffff;
int Group=0;
int W,G;
int Cmp(const void *a,const void *b)
{
return *((int *)a)-*((int *)b);
}
void init()
{
scanf("%d\n%d",&W,&G);
for (int i=1;i<=G;i++)
scanf("%d",&num[i]);
qsort(num+1,G,sizeof(num[0]),Cmp);
}
void Greedy()
{
int q=1,h=G;
while (q<=h)
{
if (q==h)
{
Group++;
return;
}
else
{
if (num[q]+num[h]>W)
{
Group++;
h--;
}
else
{
Group++;
q++;
h--;
}
}
}
}
void Print()
{
for (int i=1;i<=G;i++)
cout<<num[i]<<" ";
}
int main()
{
freopen("group.in","r",stdin);
freopen("group.out","w",stdout);
init();
Greedy();
cout<<Group<<endl;
return 0;
}
#include <cstdio>
#include <cstdlib>
using namespace std;
int num[30001];
int Max=0,Min=0xfffffff;
int Group=0;
int W,G;
int Cmp(const void *a,const void *b)
{
return *((int *)a)-*((int *)b);
}
void init()
{
scanf("%d\n%d",&W,&G);
for (int i=1;i<=G;i++)
scanf("%d",&num[i]);
qsort(num+1,G,sizeof(num[0]),Cmp);
}
void Greedy()
{
int q=1,h=G;
while (q<=h)
{
if (q==h)
{
Group++;
return;
}
else
{
if (num[q]+num[h]>W)
{
Group++;
h--;
}
else
{
Group++;
q++;
h--;
}
}
}
}
void Print()
{
for (int i=1;i<=G;i++)
cout<<num[i]<<" ";
}
int main()
{
freopen("group.in","r",stdin);
freopen("group.out","w",stdout);
init();
Greedy();
cout<<Group<<endl;
return 0;
}
沒有留言:
張貼留言