专栏文章

题解:P14635 [NOIP2025] 糖果店 / candy(民间数据)

P14635题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mimyu5ke
此快照首次捕获于
2025/12/01 17:47
3 个月前
此快照最后确认于
2025/12/01 17:47
3 个月前
查看原文

糖果购买问题 题解

题目背景

小 R 有 m 元钱,要在 n 种糖果中购买尽可能多的糖果。每种糖果的购买价格是周期变化的。

题目分析

对于第 i 种糖果:
  • 第奇数颗价格为 xix_i
  • 第偶数颗价格为 yiy_i 元 购买模式:xi,yi,xi,yi,x_i, y_i, x_i, y_i, \ldots

解题思路

省流:贪心。

关键观察

  1. 每两颗糖果的花费固定:任意连续两颗糖果总花费为 xi+yix_i + y_i
  2. 贪心策略:优先选择平均价格低的糖果批量购买

算法步骤

  1. 计算所有糖果的 sumi=xi+yisum_i = x_i + y_i
  2. sumisum_i 从小到大排序
  3. 尽量购买"两颗一组"的组合
  4. 用剩余的钱优化购买:
    • 买一颗新糖果(选最小 xix_i
    • 替换策略:用更便宜的单颗换掉贵的组合

代码实现

CPP
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long ll;

int main() {
    int n;
    ll m;
    cin >> n >> m;
    
    vector<ll> x(n), y(n), sum(n);
    ll min_x = 1e18, min_y = 1e18;
    
    for (int i = 0; i < n; i++) {
        cin >> x[i] >> y[i];
        sum[i] = x[i] + y[i];
        min_x = min(min_x, x[i]);
        min_y = min(min_y, y[i]);
    }
    
    sort(sum.begin(), sum.end());
    
    ll ans = 0;
    ll cost = 0;
    
    // 批量购买两颗一组的组合
    for (int i = 0; i < n; i++) {
        if (cost + sum[i] <= m) {
            cost += sum[i];
            ans += 2;
        } else {
            break;
        }
    }
    
    ll remaining = m - cost;
    
    // 情况1:买一颗新的糖果
    if (remaining >= min_x) {
        ans = max(ans,ans + 1);
    }
    
    // 情况2:替换策略
    if (ans >= 2) {
        ll new_remaining = remaining + sum[ans/2 - 1] - min_y;
        if (new_remaining >= min_x) {
            ans = max(ans, ans - 2 + 3);
        }
    }
    
    // 情况3:钱太少
    if (min_x > m && min_y > m) {
        ans = 0;
    }
    
    cout << ans << endl;
    
    return 0;
}
警告:代码中含有防抄袭改动,请勿直接复制!!

评论

0 条评论,欢迎与作者交流。

正在加载评论...