CCF-CSP 202209-2 何以包邮?

文章讲述了如何使用动态规划解决新学期小P同学在顿顿书城购书时,选择书籍以达到包邮条件并最小化花费的问题。给出了C++代码实现和样例分析。
摘要由CSDN通过智能技术生成

😸题目要求

🐈‍⬛题目描述

新学期伊始,适逢顿顿书城有购书满 x x x 元包邮的活动,小 P 同学欣然前往准备买些参考书。
一番浏览后,小 P 初步筛选出 n n n 本书加入购物车中,其中第 i i i ( 1 ≤ i ≤ n ) (1 \leq i \leq n) (1in) 的价格为 a i a_i ai 元。
考虑到预算有限,在最终付款前小 P 决定再从购物车中删去几本书(也可以不删),使得剩余图书的价格总和 m m m 在满足包邮条件 ( m ≤ x ) (m \leq x) (mx) 的前提下最小。

试帮助小 P 计算,最终选购哪些书可以在凑够 x x x 元包邮的前提下花费最小?

🐈‍⬛输入格式

从标准输入读入数据。

输入的第一行包含空格分隔的两个正整数 n n n x x x,分别表示购物车中图书数量和包邮条件。

接下来输入 n n n 行,其中第 i i i ( 1 ≤ i ≤ n ) (1 \leq i \leq n) (1in) 仅包含一个正整数 a i a_i ai,表示购物车中第 i i i 本书的价格。输入数据保证 n n n 本书的价格总和不小于 x x x

🐈‍⬛输出格式

输出到标准输出。

仅输出一个正整数,表示在满足包邮条件下的最小花费。

🐈‍⬛样例说明

🎶样例1输入

4 100
20
90
60
60

🎶样例1输出

110

🎶样例1解释

购买前两本书 ( 20 + 90 ) (20+90) (20+90) 即可包邮且花费最小。

🎶样例2输入

3 30
15
40
30

🎶样例2输出

30

🎶样例2解释

仅购买第三本书恰好可以满足包邮条件。

🎶样例3输入

2 90
50
50

🎶样例3输出

100

🎶样例3解释

必须全部购买才能包邮。

🐈‍⬛子任务

70% 的测试数据满足: n ≤ 15 n \leq 15 n15
全部的测试数据满足: n ≤ 30 n \leq 30 n30,每本书的价格 a i ≤ 1 0 4 a_i \leq 10^4 ai104 x ≤ a 1 + a 2 + ⋅ ⋅ ⋅ + a n x \leq a_1+a_2+···+a_n xa1+a2+⋅⋅⋅+an

🐈‍⬛提示

对于 70% 的测试数据,直接枚举所有可能的情况即可。

😸问题解决

🐈满分代码(含逐行代码解释)

🍭C++

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n, x;
	cin >> n >> x;
	vector<int>a(31); //每本书的价格
	int sum = 0;
	for(int i = 1; i <= n; i++){
		cin >> a[i];
		sum += a[i];
	}
	int temp;
	temp = sum -x; //需要选出的书籍的价格总和
	int dp[31][100001]; //这是一个动态规划的问题
	for(int i = 1; i <= n; i++){ //外层循环遍历每本书
		for(int j = 1; j <= temp; j++){ //内层循环遍历总价值不超过temp的情况
			/*
				对于每个状态dp[i][j],有两种选择:选取第i本书或不选取
				如果不选取第i本书,则dp[i][j] = dp[i-1][j];
				如果选择第i本书,则dp[i][j] = dp[i-1][j-a[i]]+a[i],取两者之间的最大值。
			*/
			dp[i][j] = dp[i-1][j];
			if(j >= a[i]){
				dp[i][j] = max(dp[i][j], dp[i-1][j-a[i]]+a[i]);
				//dp[i][j]表示在前i本书中选取总价不超过j的最大价格
			}
		}
	}
	int result = 0;
	result = sum - dp[n][temp]; //计计算选出的书籍的价格总和,并将其减去所有书籍的价格总和
	cout << result <<endl;
	return 0;
} 

🐈场景拓展

本题代码属于动态规划算法的题型。具体而言,这个问题可以称为「01背包问题」的变种。在「01背包问题」中,我们有一组物品,每个物品都有自己的重量和价值,目标是选择一些物品装入背包,使得背包的总重量不超过限制,并且价值最大化。而这个问题中,我们需要选择一些书籍的价格,使得总价格不超过限制,并且尽量高。

  • 0-1背包问题:给出一组物品的重量和价值,选择一些物品装入背包,使得背包的总重量不超过限制,而总价值最大化。
  • 完全背包问题:与0-1背包类似,但每种物品可以选择无限次放入背包。
  • 多重背包问题:与0-1背包类似,但每种物品有限定的可选次数。
  • 分组背包问题:将物品分为若干组,每组物品只能选择一个,目标是选择一些物品使得背包的总重量不超过限制,而总价值最大化。
  • 背包问题的变种:如带有约束条件、特殊要求或者多个限制条件的背包问题。
  • 29
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值