【寒假任务】 洛谷1094 纪念品分组

问题描述
元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。
输入
第1行包括一个整数w,为每组纪念品价格之和的上上限。
第2行为一个整数n,表示购来的纪念品的总件数G
第3~n+2行每行包含一个正整数Pi (5 <= Pi <= w)w表示所对应纪念品的价格。
输出
包含一个整数,即最少的分组数目。
样例输入
100
9
90
20
20
30
50
60
70
80
90
样例输出
6
算法讨论
先从大到小排序,拿最大的加最小的,标记,不行就拿第二大的,以此类推,最后把没标记的加上。有个小优化,若不管怎样都无法再组合了,那就不用再找了,直接退出。

const
  maxn=30000;
var
  a:array[1..maxn] of longint;
  f:array[1..maxn] of boolean;
  i,j,n,s,w:longint;
  flag:boolean;

procedure qsort(l,r:longint);
var
  i,j,m,t:longint;
begin
  i:=l; j:=r;
  m:=a[(l+r) div 2];
  repeat
    while a[i]>m do
      inc(i);
    while a[j]<m do
      dec(j);
    if i<=j
      then begin
             t:=a[i]; a[i]:=a[j]; a[j]:=t;
             inc(i); dec(j)
           end;
  until i>j;
  if l<j
    then qsort(l,j);
  if i<r
    then qsort(i,r)
end;

begin
  read(w);
  read(n);
  for i:=1 to n do
    read(a[i]);
  qsort(1,n);
  for i:=n downto 1 do
    begin
      flag:=false;
      for j:=1 to i-1 do
        if (f[j]=false) and (a[i]+a[j]<=w) and (i<>j)
          then begin
                 f[j]:=true;
                 f[i]:=true;
                 flag:=true;
                 inc(s);
                 break
               end;
      if flag=false
        then break 
    end;
  for i:=1 to n do
    if f[i]=false
      then inc(s);
  write(s)
end.

这里写图片描述
Pixiv ID:61481273

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值