跳跃表解决01背包问题

跳跃表解决01背包问题

挺有意思的题目

看算法设计与分析有跳跃点实现,解决空间复杂度,感觉好烧脑,就实现了一下

结果

在这里插入图片描述

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;

namespace JumpPackage
{
    //一个物品信息
    public class Item
    {
        public int weight;//重量
        public int val;//价值
        public int id;//物品编号,名字

        public Item(int w, int v, int id) 
        {
            this.weight = w;
            this.val = v;
            this.id = id;
        }
    }

    //一个背包计划
    public class Plan
    {
        public int weight;//本计划总重量
        public int val;//本计划总价值
        public bool bControl;//是否受控,是则表名有同级更优计划,处理将抛弃
        public List<int> items = new List<int>();//计划物品,对应最优解

        public Plan()
        {
            weight = 0;
            val = 0;
            bControl = false;
        }

        public Plan(int w, int v)
        {
            weight = w;
            val = v;
            bControl = false;
        }
    }

    //背包问题
    public class Problem
    {
        public int content;//背包容量,输入获得
        public List<Item> items;//所有物品,输入获得
        public List<Plan> plns = new List<Plan>();//最后处理的计划集

        public Problem(int cet, List<Item> its)
        {
            content = cet;
            items = its;
        }

        public void Process()
        {
            List<Plan> right = new List<Plan>();
            plns.Add(new Plan(0,0));//没有任何物品的计划,
            foreach (Item it in items)
            {
                right = GenerateNext(plns, it);//产生下次计划
                plns = UnionPlan(plns, right);//去除受控计划
            }
        }

        public void Answer()
        {
            Console.WriteLine("最优方案 物品数量{0} 重量{1} 价值:{2}", 
                plns[plns.Count - 1].items.Count, plns[plns.Count - 1].weight, plns[plns.Count - 1].val);

            Console.Write("背包信息:");
            foreach (var item in plns[plns.Count - 1].items)
            {
                Console.Write("物品{0}:", item);
            }

            Console.WriteLine();
            Console.WriteLine("========跳跃表信息========");
            foreach (var item in plns)
            {
                Console.Write("({0},{1}) ", item.weight, item.val);
            }
            Console.WriteLine();
        }

        /// <summary>
        /// 产生新计划
        /// </summary>
        /// <param name="left">旧计划</param>
        /// <param name="good">新的物品</param>
        /// <returns>新计划</returns>
        public List<Plan> GenerateNext(List<Plan> left, Item good)
        {
            List < Plan > next = new List<Plan>();

            foreach (var item in left)
            {
                if (item.weight + good.weight <= content)//不超重则录入
                {
                    Plan temp = new Plan(item.weight + good.weight, item.val + good.val);
                    temp.items.AddRange(item.items);
                    temp.items.Add(good.id);

                    next.Add(temp);
                }
            }

            return next;
        }

        /// <summary>
        /// 合并计划
        /// </summary>
        /// <param name="left">旧计划集</param>
        /// <param name="right">新计划集</param>
        /// <returns></returns>
        public List<Plan> UnionPlan(List<Plan> left, List<Plan> right)
        {
            List<Plan> plans = new List<Plan>();

            foreach (var lItem in left) 
            {
                foreach (var rItem in right)
                {
                    if (lItem.weight <= rItem.weight && lItem.val > rItem.val)//旧计划和新计划比较 轻或者一样重反而价值高,则标记新计划为受控计划
                    {
                        rItem.bControl = true;
                    }

                    if (rItem.weight <= lItem.weight && rItem.val > lItem.val)//新计划和旧计划比较 轻或者一样重反而价值高,则标记旧计划为受控计划
                    {
                        lItem.bControl = true;
                    }
                }
            }

            foreach (var lItem in left)
            {
                if (!lItem.bControl) 
                {
                    plans.Add(lItem);
                }
            }

            foreach (var rItem in right)
            {
                if (!rItem.bControl)
                {
                    plans.Add(rItem);
                }
            }

            plans.Sort((l, r) => {
                return l.weight < r.weight ? -1 : 1;
            });

            return plans;
        }
    }

    internal class Program
    {
        public static bool IsContinue()
        {
            Console.Write("是否继续(N/Y)?: ");
            string val = Console.ReadLine();
            while (val != "Y" && val != "y" && val != "N" && val != "n")
            {
                Console.Write("是否继续(N/Y)?: ");
                val = Console.ReadLine();
            }

            return val == "Y" || val == "y";
        }

        public static int ReadContent()
        {
            Console.Write("背包容量(正整数): ");
            string val = Console.ReadLine();
            int num;
            while (!int.TryParse(val, out num) || num <= 0)
            {
                Console.Write("输入错误,重新输入背包容量(正整数): ");
                val = Console.ReadLine();
            }

            return num;
        }

        public static int ReadCount()
        {
            Console.Write("物品数量(正整数): ");
            string val = Console.ReadLine();
            int num;
            while (!int.TryParse(val, out num) || num <= 0)
            {
                Console.Write("输入错误,重新输入物品数量(正整数): ");
                val = Console.ReadLine();
            }

            return num;
        }

        public static int ReadWeight(int idx)
        {
            Console.Write("物品{0}重量(正整数): ", idx);
            string val = Console.ReadLine();
            int num;
            while (!int.TryParse(val, out num) || num <= 0)
            {
                Console.Write("输入错误,重新输入物品{0}重量(正整数): ", idx);
                val = Console.ReadLine();
            }

            return num;
        }

        public static int ReadValue(int idx)
        {
            Console.Write("物品{0}价值(正整数): ", idx);
            string val = Console.ReadLine();
            int num;
            while (!int.TryParse(val, out num) || num <= 0)
            {
                Console.Write("输入错误,重新输入物品{0}价值(正整数): ", idx);
                val = Console.ReadLine();
            }

            return num;
        }

        static void Main(string[] args)
        {
            do
            {
                List<Item> items = new List<Item>();
                int content = ReadContent();
                int cnt = ReadCount();
                for (int idx = 0; idx < cnt; idx++)
                {
                    items.Add(new Item(ReadWeight(idx+1), ReadValue(idx+1), idx+1));
                }
                Problem problem = new Problem(content, items);
                problem.Process();
                problem.Answer();
            } while (IsContinue());
        }
    }
}

程序和代码已上传,可以下载直接test

程序和代码

参考

主要是看b站张老师的课程
跳跃点 背包问题

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第十篇【传奇开心果短博文系列】鸿蒙开发技术点案例示例:深度解读鸿蒙全场景适配

传奇开心果短博文系列 系列短博文目录鸿蒙开发技术点案例示例系列 短博文目录前言一、鸿蒙全场景适配实现介绍二、统一核心示例代码三、设备驱动框架示例代码四、统一界面框架示例代码五、自适应布局示例代码六、分布式能力示例代码七、跨平台开发示例代码八、设备能力开放示例…

AP6317 同步3A锂电充电IC 带散热 便携式设备 充电器

概述是一款面向5V交流适配器的3A锂离子电池充电器。它是采用800KHz固定频率的同步降压型转换器&#xff0c;因此具有高达92%以上的充电效率&#xff0c;自身发热量极小。包括完整的充电终止电路、自动再充电和一个度达1%的4.2V预设充电电压&#xff0c;内部集成了防反灌保护、输…

使用ChatGPT学习大象机器人六轴协作机械臂mechArm

引言 我是一名机器人方向的大学生&#xff0c;近期学校安排自主做一个机器人方面相关的项目。学校给我们提供了一个小型的六轴机械臂&#xff0c;mechArm 270M5Stack&#xff0c;我打算使用ChatGPT让它来辅助我学习如何使用这个机械臂并且做一个demo。 本篇文章将记录我是如何使…

jsp 产品维修管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 产品维修管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.…

【51单片机系列】应用设计——8路抢答器的设计

51单片机应用——8路抢答器设计 文章设计文件及代码&#xff1a;资源链接。 文章目录 要求&#xff1a;设计思路软件设计仿真结果 要求&#xff1a; &#xff08;1&#xff09; 按下”开始“按键后才开始抢答&#xff0c;且抢答允许指示灯亮&#xff1b; &#xff08;2&…

2024年第七届亚洲能源与电气工程会议 (ACEEE 2024)

2024年第七届亚洲能源与电气工程会议 (ACEEE 2024)将于2024年7月20-22日在中国成都举行。本次会议由电子科技大学主办&#xff0c;电子科技大学机械与电气工程学院承办。ACEEE 2024旨在为推动能源与电气工程领域科学研究的发展&#xff0c;增进各国学者之间的学术交流&#xff…

备战蓝桥杯---数据结构与STL应用(进阶1)

让我们先来看一看map的基础应用吧&#xff1a; 下面是实现代码&#xff1a; #include<bits/stdc.h> using namespace std; typedef map<int,multiset<int> > line; map<int,multiset<int> >mx; map<int,multiset<int> >my; int n,m…

《Docker技术革命:从虚拟机到容器化,全面解析Docker的原理与应用-上篇》

文章目录 Docker为什么会出现总结 Docker的思想Docker历史总结 Docker能干嘛虚拟机技术虚拟机技术的缺点 容器化技术Docker和虚拟机技术的区别 Docker概念Docker的基本组成镜像&#xff08;image)容器&#xff08;container&#xff09;仓科&#xff08;repository&#xff09;…

Vulnhub靶机:hackme2-DHCP

一、介绍 运行环境&#xff1a;Virtualbox(攻击机)和VMware(靶机) 攻击机&#xff1a;kali&#xff08;192.168.56.106&#xff09; 靶机&#xff1a;hackme2-DHCP&#xff08;192.168.56.107&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1…

【lesson31】MySQL视图

文章目录 视图介绍基本使用创建视图案例删除视图 视图规则和限制 视图介绍 视图是一个虚拟表&#xff0c;其内容由查询定义。同真实的表一样&#xff0c;视图包含一系列带有名称的列和行数据。视图的数据变化会影响到基表&#xff0c;基表的数据变化也会影响到视图。 基本使用…

GitLab16.8配置webhooks、Jenkins2.4配置GitLab插件实现持续集成、配置宝塔面板实现持续部署(其三)

看本篇文章的前提是已经部署完GItlab和Jenkins服务器&#xff0c;已经可以手动构建成功&#xff0c;并且经过了很多次实践&#xff0c;对这两款软件基本熟悉。 建议大家按以下顺序看 前端自动化&#xff08;其一&#xff09;部署gitlab 前端自动化&#xff08;其二&#xff0…

百无聊赖之JavaEE从入门到放弃(十四)异常

目录 一.异常机制 二.异常分类 三.异常的处理方式 1.捕获异常(try-catch-finally) 2.声明异常&#xff08;throws 子句&#xff09; 四.try-with-resource 五.自定义异常 六.IDEA 调试 debug 一.异常机制 工作中&#xff0c;程序遇到的情况不可能完美。比如&#xff1a…

Zabbix数据库分离与邮件报警

基础环境&#xff1a;要有zabbix服务端与被监控端实验目标&#xff1a;源数据库与服务端存放在一台服务器上&#xff0c;分离后源数据库单独在一台服务器上&#xff0c;zabbix服务端上不再有数据库。环境拓扑图&#xff1a; 实验步骤&#xff1a; 1.在8.7服务器上安装相同版本…

单片机驱动多个ds18b20

目录 1设计内容 2ds18b20介绍 2.1传感器引脚及原理图 2.2寄存器配置 3程序实现 3.1配置初始化 3.2配置寄存器 3.3ROM读取 3.4温度读取 1设计内容 通过51单片机&#xff0c;读取总线上挂载的多个ds18b20的温度信息。 如下图&#xff0c;成功读取到3路温度数据。 2ds18…

MD5算法:高效安全的数据完整性保障

摘要&#xff1a;在数字世界中&#xff0c;确保数据完整性和安全性至关重要。消息摘要算法就是一种用于实现这一目标的常用技术。其中&#xff0c;Message Digest Algorithm 5&#xff08;MD5&#xff09;算法因其高效性和安全性而受到广泛关注。本文将详细介绍MD5算法的优缺点…

双屏联动系统在展厅设计中的互动类型与效果

随着各项多媒体技术的快速发展&#xff0c;让展厅中的各类展项得到技术升级&#xff0c;其中作为电子设备中最基础的显示技术&#xff0c;不仅优化了内容的展示质量&#xff0c;还实现了更具互动性的创新技术&#xff0c;如双屏联动系统就是当前展厅设计中最常见的技术类型之一…

TS项目实战一:流淌的字符动画界面

使用ts实现虚拟世界&#xff0c;创建ts项目&#xff0c;并编写ts代码&#xff0c;使用tsc编译后直接加载到html界面&#xff0c;实现类似黑客帝国中的流淌的代码界面的效果。 源码下载地址&#xff1a;点击下载 讲解视频 TS实战项目一&#xff1a;数字流界面项目创建 TS实战项…

Airflow原理浅析

⭐️ airflow基本原理 Apache Airflow 是一个开源的工作流自动化工具&#xff0c;它用于调度和管理复杂的数据工作流。Airflow 的原理基于有向无环图&#xff08;DAG&#xff09;的概念&#xff0c;它通过编写和组织任务的有向图来描述工作流程。 以下是 Apache Airflow 的一…

解决ModuleNotFoundError: No module named ‘pysqlite2‘

目录 一、问题描述 二、问题分析 三、解决方法 四、参考文章 一、问题描述&#xff1a; 新建conda编译环境。安装Jupyter后打不开&#xff0c;报错&#xff1a; 二、问题分析&#xff1a; 缺少sqlite3动态链接库 三、解决方法&#xff1a; SQLite Download Page 下载…

go语言socket编程

1.互联网分层模型 过程分析&#xff1a; 2.Socket图解 Socket是应用层与TCP/IP协议族通信的中间软件抽象层。在设计模式中&#xff0c;Socket其实就是一个门面模式&#xff0c;它把复杂的TCP/IP协议族隐藏在Socket后面&#xff0c;对用户来说只需要调用Socket规定的相关函数&a…