机试题——年会奖品分配策略

题目描述

公司准备在年会上开展抽奖活动。他们购买了若干个奖品,每个奖品都有一个价格,用一个正整数数组表示。在抽奖环节,公司准备设置一等奖、二等奖和三等奖,每个等级设置一个奖品,并将所有奖品分成三份大礼包。公司希望尽可能地减小一等奖和三等奖之间的价格差异,同时满足一等奖总价格大于二等奖总价格,二等奖总价格大于三等奖总价格。

输入描述

  • 第一行:正整数 n,表示奖品的数量,取值范围 [3,16)
  • 第二行:一个正整数数组 array,每个元素表示奖品的价格,取值范围 [1,1000]

输出描述

一个非负整数,表示一等奖和三等奖的差值,没有方案返回 0

用例输入

3
5 4 2
3
4
10 5 4 2
5

分配方案有多种,一等奖和三等奖差值最小的方案是 10,6,5

解题思路

  1. 暴力搜索

    • 使用深度优先搜索(DFS)枚举所有可能的分配方案。对于每个奖品,尝试将其分配到一等奖、二等奖或三等奖中。
    • 在搜索过程中,剪枝以减少不必要的计算。例如,如果当前分配方案已经无法满足 x > y > z 的条件,则直接跳过该方案。
    • 记录所有满足条件的方案中,一等奖和三等奖价格差的最小值。
  2. 剪枝优化

    • 在分配过程中,实时计算剩余未分配的奖品总价值。如果当前分配方案即使加上所有剩余奖品也无法满足 x > y > z 的条件,则直接跳过该方案。

代码

#include <iostream>
#include <vector>
#include <queue>
#include <sstream>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;
int n;
vector<int> nums(20);
int res = 1000000;

// 当前遍历到的下标 一等 二等 三等 剩余未用的价格
void dfs(int cur, int i, int j, int k, int s) {
    if (cur == n) {
        // 结束
        if (i > j && j > k) {
            res = min(res, i - k);
        }
        return;
    }
    // 全部给了也不符合结果的直接pass
    if (i + s < j || i + s < k || j + s < k) return;

    // 开始分配 暴力搜索
    dfs(cur + 1, i + nums[cur], j, k, s - nums[cur]);
    dfs(cur + 1, i, j + nums[cur], k, s - nums[cur]);
    dfs(cur + 1, i, j, k + nums[cur], s - nums[cur]);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n;
    int all = 0;
    for (int i = 0; i < n; i++) {
        cin >> nums[i];
        all += nums[i];
    }
    dfs(0, 0, 0, 0, all);
    if (res == 1000000) res = 0; // 如果没有找到方案,返回0
    cout << res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值