信息学奥赛一本通 1939:【07NOIP普及组】纪念品分组 | P1094 [NOIP2007 普及组] 纪念品分组

【题目链接】

ybt 1939:【07NOIP普及组】纪念品分组
洛谷 P1094 [NOIP2007 普及组] 纪念品分组

【题目考点】

1. 贪心

【解题思路】

贪心选择:选择价格最小的和最大的纪念品分成一组,若价格最小的和最大的纪念品无法
分成一组,那么价格最大的纪念品单独一组。

将问题抽象为:有n个数字,要凑成加和小于等于w的组,一组可以有2个数或1个数,最少可以凑多少组。

1. 贪心选择性质的证明:

贪心选择:
如果最大值加最小值大于w,那么最大值单独一组。
如果最大值加最小值小于等于w,最大最小值凑成一组。

  1. 证明:存在最优解包含第一次贪心选择

如果第一次选择的组只有最大值,由于最大值无法和其他数字凑成一组,最大值单独一组是唯一的选择。
如果第一次的贪心选择是最大最小值构成的一组。设最大值为 l l l,最小值为 g g g,那么一定有: l + g ≤ w l+g\le w l+gw
假设对于所有最优解,都不包含第一次的贪心选择,也就是说 l l l g g g不会分为一组。
l l l可以有以下几种情况

  1. l l l单独一组:无论 g g g与另一个数字一组,还是 g g g单独一组,都可以让 g g g更改为与 l l l一组。
  2. l l l与另一个数字 x x x一组,那么有 l + x ≤ w l+x\le w l+xw
    假设此时 g g g单独一组,那么可以让 g g g x x x交换,得到 l l l g g g一组。
    假设此时 g g g与另一个数字 h h h一组,那么有 h + g ≤ w h+g\le w h+gw
    由于 l l l是当时的最大值,那么一定有 h ≤ l h\le l hl,所以有 h + x ≤ l + x ≤ w h+x\le l+x\le w h+xl+xw h h h x x x一组加和并不会超过 w w w。 将 g g g x x x交换, l l l g g g一组, h h h x x x一组,是可行的。
    无论什么情况,都可以通过交换使得 l l l g g g一组,这样做分组数量不会增加,该方案仍然是最优解,最优解中包含了贪心选择,与假设相悖,原命题得证。
  1. 证明:进行k次贪心选择后,存在最优解包含第k+1次的贪心选择。

证明方法与证明第1点相似,不再赘述。

2.具体做法:

对所有纪念品按升序排序,设l,r两个指针指向当前看到的价格最小和最大的纪念品。

  • 如果第l和第r个纪念品的价格加和大于w,那么第l纪念品单独一组,l加1。
  • 如果第l和第r个纪念品的价格加和小于等于w,那么第l和第r纪念品分为一组,l和r都加1。

【题解代码】

解法1:贪心
#include<bits/stdc++.h>
using namespace std;
#define N 30005
int main()
{
    int p[N], w, n, ct = 0;//ct:组数
    cin >> w >> n;
    for(int i = 1; i <= n; ++i)
        cin >> p[i];
    sort(p+1, p+1+n);
    int l = 1, r = n;
    while(l <= r)
    {
        if(l != r && p[l] + p[r] <= w)
        {
            l++;
            r--;
            ct++;//l, r凑一组
        }
        else
        {
            r--;
            ct++;//r自己凑一组 
        }
    }
    cout << ct;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值