【0-1背包变式题】何以包邮(来自Acwing寒假每日一题)

news2024/11/18 3:42:27

⭐️前面的话⭐️

本篇文章介绍来自一道0-1背包的变式原题,展示语言java/C++。

📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创,CSDN首发!
📆首发时间:🌴2022年7月25日🌴
✉️坚持和努力一定能换来诗与远方!
💭推荐书籍:📚《算法》,📚《算法导论》
💬参考在线编程网站:🌐牛客网🌐力扣
博主的码云gitee,平常博主写的程序代码都在里面。
博主的github,平常博主写的程序代码都在里面。
🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!


📌导航小助手📌

  • ⭐️何以包邮⭐️
    • 🔐题目详情
    • 💡解题思路
    • 🔑源代码
  • 🌱总结


⭐️何以包邮⭐️

🔐题目详情

4700. 何以包邮?

新学期伊始,适逢顿顿书城有购书满 x 元包邮的活动,小 P 同学欣然前往准备买些参考书。

一番浏览后,小 P 初步筛选出 n 本书加入购物车中,其中第 i 本(1≤i≤n)的价格为 ai 元。

考虑到预算有限,在最终付款前小 P 决定再从购物车中删去几本书(也可以不删),使得剩余图书的价格总和 m 在满足包邮条件(m≥x)的前提下最小。

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

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

接下来输入 n 行,其中第 i 行(1≤i≤n)仅包含一个正整数 ai,表示购物车中第 i 本书的价格。

输入数据保证 n 本书的价格总和不小于 x。

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

数据范围
70% 的测试数据满足:n≤15;
全部的测试数据满足:n≤30,每本书的价格 a i ≤ 1 0 4 a_i≤10^4 ai104 且 x≤a1+a2+⋯+an。

输入样例1:
4 100
20
90
60
60
输出样例1:
110
样例1解释
购买前两本书 (20+90) 即可包邮且花费最小。

输入样例2:
3 30
15
40
30
输出样例2:
30
样例2解释
仅购买第三本书恰好可以满足包邮条件。

输入样例3:
2 90
50
50
输出样例3:
100
样例3解释
必须全部购买才能包邮。

💡解题思路

0-1背包问题
思路1:典型的0-1背包是求不超过某容量的最大价值,该题需要我们求超过某数的最小值,我们可以使用逆向思维,我们不直接入手,要求不超过 x x x的最小总价格,我们先可以将所有的商品全部选好,得到总价格 s u m sum sum,然后再从选好的商品中选出若干件,但是需要控制剩下来的总价值不小于 x x x,所以我们可以从这些商品中选择若干件,要想总价格不低于 x x x,最多只能选择 m = s u m − x m=sum-x m=sumx价值的商品移除,因此问题就转化为: n n n件商品中选择若干件,不超过 m m m的最大总价格。,此时问题就转化为经典的0-1背包问题了。

  • 状态定义:定义 f [ i ] [ j ] f[i][j] f[i][j]表示从前 i i i件物品中选,总价值不超过 j j j的最大总价值。
  • 状态属性:最大值
  • 初始状态:从 0 0 0件商品中选,最大价格为 0 0 0,因此 f [ 0 ] [ j ] = 0 f[0][j]=0 f[0][j]=0
  • 状态转移情况:考虑是否选择第 i i i件商品,不妨设第 i i i件商品价格为 t t t
    • 不选择第 i i i件商品, f [ i ] [ j ] = f [ i − 1 ] [ j ] f[i][j]=f[i - 1][j] f[i][j]=f[i1][j]
    • 选择第 i i i件商品, f [ i ] [ j ] = f [ i − 1 ] [ j − t ] + t f[i][j]=f[i-1][j-t]+t f[i][j]=f[i1][jt]+t
  • 状态转移方程: f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − t ] + t ) f[i][j]=max(f[i-1][j], f[i-1][j-t]+t) f[i][j]=max(f[i1][j],f[i1][jt]+t)
  • 一维优化后状态转移方程: f [ j ] = m a x ( f [ j ] , f [ j − t ] + t ) f[j]=max(f[j],f[j-t]+t) f[j]=max(f[j],f[jt]+t)

思路2:直接求。

  • 状态定义:不妨定义 f [ i ] [ j ] f[i][j] f[i][j]表示在前 i i i件物品中选择,超过 j j j的最小价格。
  • 状态属性:最小值
  • 初始化: f [ 0 ] [ 0 ] = 0 , f [ 0 ] [ j ] = I N F , j > 0 f[0][0]=0, f[0][j]=INF,j>0 f[0][0]=0,f[0][j]=INF,j>0
  • 状态转移情况,对于第 i i i个商品,我们可以选择选或者不选,不妨设第 i i i件商品的价格为 t t t
    • 不选择, f [ i ] [ j ] = f [ i − 1 ] [ j ] f[i][j]=f[i-1][j] f[i][j]=f[i1][j]
    • 选择,当前状态为前一行 j − t j-t jt状态时的价格加上 t t t,如果 j < t j<t j<t,取 0 0 0状态的价格加上 t t t,即 f [ i ] [ j ] = f [ i − 1 ] [ m a x ( 0 , j − t ) ] + t f[i][j]=f[i-1][max(0,j-t)]+t f[i][j]=f[i1][max(0,jt)]+t
  • 状态转移方程: f [ i ] [ j ] = m i n ( f [ i − 1 ] [ j ] , f [ i − 1 ] [ m a x ( 0 , j − t ) ] + t ) f[i][j]=min(f[i-1][j], f[i-1][max(0, j-t)]+t) f[i][j]=min(f[i1][j],f[i1][max(0,jt)]+t)
  • 一维优化转移方程: f [ j ] = m i n ( f [ j ] , f [ m a x ( 0 , j − t ) ] + t ) f[j]=min(f[j], f[max(0, j-t)]+t) f[j]=min(f[j],f[max(0,jt)]+t)

🔑源代码

思路1,Java代码:

import java.util.*;

class Main {
    private static final int N = (int) 33, M = (int) 3e5 +23;
    
    private static int[] a = new int[N], f = new int[M];
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        int n = sc.nextInt();
        int x = sc.nextInt();
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextInt();
            sum += a[i];
        }
        int m = sum - x;
        
        Arrays.fill(f, 0);
        
        for (int i = 1; i <= n; i++) {
            int t = a[i];
            for (int j = m; j >= t; j--) {
                f[j] = Math.max(f[j], f[j - t] + t);
            }
        }
        
        System.out.println(sum - f[m]);
    }
}

思路1,C++代码:

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;
const int N =33, M = (int) 3e5 + 23;
int a[N], f[M];

int main()
{
    int n, x;
    int sum = 0;
    cin >> n >> x;
    for (int i = 1; i <= n; i++) 
    {
        cin >> a[i];
        sum += a[i];
    }
    
    int m = sum - x;
    
    memset(f, 0, sizeof(f));
    
    //0-1背包
    for (int i = 1; i <= n; i++) 
    {
        int t = a[i];
        for (int j = m; j >= t; j--) 
        {
            f[j] = max(f[j], f[j - t] + t);
        }
    }
    
    cout << sum - f[m] << endl;
    
    return 0;
}

思路2,Java代码:

import java.util.*;

class Main {
    private static final int N = 33, M = (int) 3e5 + 33;
    
    private static int[] a = new int[N], f = new int[M];
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        int n = sc.nextInt();
        int x = sc.nextInt();
        
        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextInt();
        }
        Arrays.fill(f, 0x3f3f3f3f);
        
        f[0] = 0;
        for (int i = 1; i <= n; i++) {
            int t = a[i];
            for (int j = x; j >= 0; j--) {
                f[j] = Math.min(f[j], f[Math.max(j - t, 0)] + t);
            }
        }
        System.out.println(f[x]);
    }
}

思路2,C++代码:

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;
const int N = 33, M = (int) 3e5 + 233;

int a[N], f[M];

int main()
{
    int n, x;
    cin >> n >> x;
    
    for (int i = 1; i <= n; i++) cin >> a[i];
    memset(f, 0x3f, sizeof(f));
    f[0] = 0;
    for (int i = 1; i <= n; i++) 
    {
        int t = a[i];
        for (int j = x; j >= 0; j--) 
        {
            f[j] = min(f[j], f[max(j - t, 0)] + t);
        }
    }
    
    cout << f[x] << endl;
    
    return 0;
}

🌱总结

0-1背包变式题。


觉得文章写得不错的老铁们,点赞评论关注走一波!谢谢啦!

1-99

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/195324.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

振弦采集模块监测传感器频率值不稳定

振弦采集模块监测传感器频率值不稳定 基本概念 振弦传感器&#xff1a;&#xff08;vibrating wire sensor&#xff09;是以拉紧的金属钢弦作为敏感元件的谐振式传感器。当弦的长度确定之后&#xff0c;其固有振动频率的变化量即可表征钢弦所受拉力的大小。根据这一特性原理&a…

2023华数杯B题社会稳定预警研究的材料支撑以及解题思路【全网独家社会稳定预警研究材料支撑】

B题社会稳定预警研究 材料支撑&#xff1a;&#xff08;动态链接&#xff0c;后期会一直不断新增支撑论文进去&#xff09; 社会稳定预警研究材料支撑合集下载 部分截图如下&#xff1a;&#xff08;还会不断更新&#xff09; 题目问题B&#xff1a;社会稳定预警研究 人类和…

【C语言】文件相关函数详解

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;别人可以拷贝我的模式&#xff0c;但不能拷贝我不断往前的激情 &#x1f6f8;C语言专栏&#xff1a;https://blog.csdn.net/vhhhbb/category_12174730.html 小苏希望大家能从这篇文章中收获到许…

C++类基础(四)

访问限定符与友元 ● 使用 public/private/protected 限定类成员的访问权限 //main.cpp struct Str { //结构体默认的访问权限&#xff0c;可以省略 //public:int x 0; private:int y 0; };int main() {Str m_str;//OK: 在同一个翻译单元内&#xff0c;结构体struct Str { .…

单车价值超整车售价?智能汽车「新赛道」扎堆供应商

汽车网络安全赛道正在进入新周期。 1月初&#xff0c;HL Mando与全球汽车网络安全方案提供商Argus Cyber Security达成协议&#xff0c;扩大网络安全技术合作。前者将Argus CAN入侵检测系统&#xff08;IDS&#xff09;解决方案应用于刹车和转向等电气化系统产品。 目前&#x…

希尔排序基本思想示例及代码

希尔排序是插入排序的一种&#xff0c;直接插入排序相关内容可见&#xff1a; https://blog.csdn.net/weixin_43978384/article/details/128836898?spm1001.2014.3001.5502 1、算法思想 希尔排序又称“缩小增量”的排序&#xff0c;属于插入排序的一种。希尔排序的基本思想是…

Springboot+ssm企业员工考勤管理系统

毕业的进度&#xff1a; 第一阶段 系统概要设计&#xff0c;设计系统架构&#xff0c;数据库模型 第二阶段 完成模块的开发与测试 第三阶段 实现主要模块 本公司员工管理系统的设计与实现以Springboot作为框架&#xff0c;B/S模式以及MySql作为后台运行的数据库。…

2023年深圳积分入户考这个软考高级证书错不了!加分真高!

信息系统项目管理师是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目之一&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职称资…

最完整的文档成像工具包:GdPicture.NET Crack

GdPicture.NET企业级智能 PDF 和文档处理 SDK&#xff0c;使用最先进的人工智能、机器学习和模糊逻辑算法的高度复杂的 API 集。经过超过 15 年专注于创新的持续研究&#xff0c;GdPicture.NET 已成为市场上最全面的PDF、OCR、条形码、文档图像和格式的 SDK 。 最佳文档影像 SD…

设计模式之装饰器模式,以C++为例。

昨天更新了适配器&#xff0c;今天来盘一盘装饰器模式。装饰器模式以一种动态的方式给对象添加额外的职责&#xff0c;好似“装饰”在对象身上一样&#xff0c;通常通过继承和委托来实现。 目录 一、装饰器模式介绍 二、游戏人物如何使用装饰器模式 三、进阶写法&#xff08;…

VScode ssh远程登陆到服务器阅读代码

1、背景介绍在工作中经常使用ssh远程访问服务阅读代码&#xff0c;但是通过ssh远程访问后没有图形界面&#xff0c;阅读代码非常不方便&#xff0c;本文向大家介绍使用VScode通过ssh远程登陆到服务器&#xff0c;本地可视化阅读查看服务器的代码文件。2、安装VS CodeVisual Stu…

Nginx优化

一.设置Nginx运行进程个数 1.查看cpu个数 grep processor /proc/cpuinfo 使用top 按1,也可以查看cpu的核心数 2.设置Nginx进程数 我的cpu数量是4,修改为4 vim /usr/local/nginx/conf/nginx.conf 二.Nginx运行CPU亲和力 vim /usr/local/nginx/conf/nginx.conf 4核4线程配置 注…

叠氮试剂1379690-01-3,3-Azido-D-alanine HCl,3-叠氮-D-丙氨酸HCl

产品规格&#xff1a;3-叠氮-D-丙氨酸HCl&#xff0c;3-Azido-D-alanine HCl1.CAS号&#xff1a;1379690-01-32.分子式&#xff1a;C3H7ClN4O23.分子量&#xff1a;166.566284.包装规格&#xff1a;1g&#xff0c;5g&#xff0c;10g&#xff0c;包装灵活&#xff0c;有100mg包装…

06-Servlet

目录1.Servlet 技术a)什么是 Servletb)手动实现 Servlet 程序&#xff01;这里要自己引入jar包&#xff0c;配置一下tomcat服务器c)url 地址到 Servlet 程序的访问d)Servlet 的生命周期e)GET 和 POST 请求的分发处理f) 通过继承 HttpServlet 实现Servlet 程序g)使用 IDEA 创建S…

小程序项目学习--第八章:播放页功能-代码重构-分包优化-打包发布

第八章:播放页功能-代码重构-分包优化-打包发布 01_(掌握)播放页-歌词分页的上下滚动区域 隐藏滚动条 .lyric-list ::-webkit-scrollbar {display: none; }歌词分页的上下滚动区域动态设置样式 思考什么时候是第一句歌词&#xff0c;什么时候是最后一句歌词 <swiper-ite…

嘉明的云计算与大数据学习之大数据综合实验案例

1.实验环境 (1)Linux:Ubuntu 16.04。 虚拟机镜像下载链接&#xff1a;https://pan.baidu.com/s/1i_B-2rAfPM53jf7Besi0tw 提取码&#xff1a;WZJM (2)MySQL:5.7.16。 (3)Hadoop:2.7.1。 (4)HBase:1.1.5。 (5)Hive:1.2.1。 (6)Sqoop:1.4.6。 (7)R:4.1.2。 (8)Eclipse:3.8。 2.…

Docklight Scripting模拟串行端口

Docklight Scripting模拟串行端口 Docklight是测试、分析和模拟串行端口(RS232、RS485/422等)的工具。此程序允许您监视和测试两个串行端口之间的连接。该程序环境简单&#xff0c;安装在所有Windows XP/7/8/10版本上。Docklight Scripting是一种带有内部编辑器的脚本语言&…

电子会议桌牌——网络版

产品特征&#xff1a; 低功耗&#xff0c;常规使用3-5年电池寿命支持空中唤醒&#xff0c;刷新快速&#xff0c;几秒钟内看到结果点阵电子纸屏幕&#xff0c;视角接近180基于Web的应用界面&#xff0c;支持跨平台操作安装简单&#xff0c;快速布置电池供电不需要布线双面显示…

Python你绝对不知道的15个小技巧,知道的算我输

名字&#xff1a;阿玥的小东东 学习&#xff1a;Python语言、正在学习c语言 主页&#xff1a;阿玥的小东东 目录 前言 1.all or any 2.bashplotlib 3.collections 4.dir 5.from __future__ import 6.python的优点 7.geopy 8.python2.x中的编码不是 unicode &#xff…

转行自学Java没后悔,我的经历证明,改变永远没有错

我在北京工作6年&#xff0c;现在年薪42万&#xff08;仅代表个人收益&#xff09;&#xff0c;目前在搜狐畅游工作&#xff0c;参与过轩辕剑的项目研发&#xff0c;有几个大型项目实战的经历&#xff0c;不过最后这几款项目都失败了。我之所以选择当初学习Java&#xff0c;就一…