首页 > 其他分享 >动态规划——背包问题

动态规划——背包问题

时间:2024-04-04 20:32:30浏览次数:11  
标签:10 背包 cout weight int 物品 动态 规划

问题描述

一个旅行者有一个最多能装10公斤的背包,现在有5中物品,每件的重量分别是2、2、6、5、4公斤,每件物品的价值分别为6、3、5、4、6, 需要将物品放入背包中,要怎么样放才能保证背包中物品的总价值最大?

算法分析 

一个旅行者有一个最多能装m公斤的背包,现在有n种物品,每件的重量分别是W1、W2、……、Wn,每件物品的价值分别为C1、C2、……、Cn, 需要将物品放入背包中,要怎么样放才能保证背包中物品的总价值最大?

如果要到达V(i,j)这一个状态有几种方式?

第一种是第i件商品没有装进去,第二种是第i件商品装进去了。

没有装进去,就是V(i-1,j);如果装进去第i件商品,是V(i-1,j-w(i))

由于最优性原理,V(i-1,j-w(i))就是前面决策造成的一种状态,后面的决策就要构成最优策略。两种情况进行比较,得出最优。

输入样例 

背包的最大容量:10

物品的数量:5

物品的重量:2  2  6  5  4

物品的价值:6  3  5  4  6

输出样例

  物品信息菜单栏
********************
编号    重量    价值
  1         2         6
  2         2         3
  3         6         5
  4         5         4
  5         4         6

记录物品装入后的背包状态:
1    2    3    4    5    6    7     8     9    10

0    6    6    6    6    6    6     6     6     6
0    6    6    9    9    9    9     9     9     9
0    6    6    9    9    9    9    11   11   14
0    6    6    9    9    9   10   11   13   14
0    6    6    9    9   12  12   15   15   15
选中的物品是:1  2  5
最大物品价值为: 15

程序运行截图

 程序代码

#include <iostream>
#include<iomanip>//用于引入setw,设置输出格式
using namespace std;
int V[100][100];//前i个物品装入容量为j的背包中获得的最大价值
/*返回两数中的较大者*/
int max(int a, int b) {
    if (a >= b)
        return a;
    else
        return b;
}
int KnapSack(int n, int weight[], int value[], int C) {
    /*填表,其中第一行和第一列全为0,即V(i,0)=V(0,j)=0;*/
    for (int i = 0; i <= n; i++)
        V[i][0] = 0;
    for (int j = 0; j <= C; j++)
        V[0][j] = 0;
    /*输出物品重量单价等信息*/
    cout << endl << "   " << "物品信息菜单栏" << endl << "********************" << endl;
    cout << "编号\t重量\t价值\t" << endl; //菜单栏 1
    for (int m = 1; m <= n; m++) //m为物品编号
    {
        cout << " " << m << "\t " << weight[m - 1] << "\t " << value[m - 1] << endl;
    }
    /*输出背包装入物品后的状态*/
    cout << endl << "记录物品装入后的背包状态:" << endl;
    for (int k = 1; k <= C; k++)
    {
        cout << std::left << setw(5) << k;//使用setw()函数设置输出宽度为5
    }
    cout << endl << endl;
    /*动态规划算法,求最大价值*/
    for (int i = 1; i <= n; i++) {// 遍历每个物品
        for (int j = 1; j <= C; j++) {// 遍历每个容量
            if (j < weight[i - 1]) { //包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的
                V[i][j] = V[i - 1][j];
                cout << std::left << setw(5) << V[i][j];
            }
            else { //还有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个
                V[i][j] = max(V[i - 1][j], V[i - 1][j - weight[i - 1]] + value[i - 1]);
                cout << std::left << setw(5) << V[i][j];
            }
        }
        cout << endl;
    }
    return V[n][C];
}
/*回溯判断哪些物品被选中装入背包*/
void Judge(int C, int n, int weight[])
{
    int j = C;
    int* state = new int[n];
    for (int i = n; i >= 1; i--) {
        if (V[i][j] > V[i - 1][j]) {
            state[i] = 1;
            j = j - weight[i - 1];
        }//如果装了就标记,然后减去相应容量
        else {
            state[i] = 0;
        }
    }
    cout << "选中的物品是:";
    for (int b = 1; b <= n; b++) {
        if (state[b] == 1) {
            cout << b << " ";
        }
    }
    cout << endl;
}
int main() {
    int n;              //物品数量
    int Capacity;       //背包最大容量
    cout << "请输入背包的最大容量:";
    cin >> Capacity;
    cout << "输入物品数:";
    cin >> n;
    int* weight = new int[n]; //物品的重量
    int* value = new int[n];  //物品的价值
    cout << "请分别输入物品的重量:";
    for (int i = 0; i < n; i++) {
        cin >> weight[i];
    }
    cout << "请分别输入物品的价值:";
    for (int c = 0; c < n; c++) {
        cin >> value[c];
    }
    int s = KnapSack(n, weight, value, Capacity); //获得的最大价值
    Judge(Capacity, n, weight);                   //调用函数判断那些物品被选择
    cout << "最大物品价值为: " << s << endl;
    delete[] weight;
    delete[] value;//释放动态数组空间
    return 0;
}

标签:10,背包,cout,weight,int,物品,动态,规划
From: https://blog.csdn.net/weixin_63131750/article/details/137294514

相关文章

  • Prometheus+Alertmanager+Node_exporter监控系统并动态配置数据库告警规则发送动态通
    前提需求:告警规则和告警发送通知策略都动态配置在数据库,方便管理和随时修改、删除。Prometheus需要动态读取数据库配置的告警规则,并根据数据的通知策略(邮件、短信、钉钉、微信等)把告警发送出去。需求分析:下面主要从表设计、组件配置、代码逻辑设计几个方面介绍。1.表设计1.1......
  • SQLite下一代查询规划器(十)
     返回:SQLite—系列文章目录   上一篇:SQLite查询优化器概述(九)下一篇:SQLite的架构(十一)1. 引言“查询规划器”的任务是弄清楚找出完成SQL语句的最佳算法或“查询计划”。从SQLite 版本3.8.0 (2013-08-26)开始,查询规划器组件已重写,使其运行得更快并生成更好的......
  • php实现动态网站静态化
    用PHP实现:将动态网站整个网站静态化时用到(不光可以静态化PHP的网站,其他语言的也可以)1、站点目录下创建index.php文件:<?php//站点域名Sta::srart("https://域名");classSta{publicstatic$domain='';publicstaticfunctionsrart($domain){......
  • Dubbo源码解析-Provider端监听注册中心动态配置原理
    上篇我们介绍了provider服务暴露源码,地址如下Dubbo源码解析-Provider服务暴露Export源码解析_dubboexporter-CSDN博客    本文主要针Dubbo服务端注册中心节点,实现动态配置变更原理,从dubbo源码角度进行解析。    Dubbo服务端动态配置原理比较简单,也是面试......
  • 常见面试题--动态规划介绍(附C++源码实现)
    关注我,持续分享逻辑思维&管理思维;可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导;有意找工作的同学,请参考博主的原创:《面试官心得--面试前应该如何准备》,《面试官心得--面试时如何进行自我介绍》, 《做好面试准备,迎接2024金三银四》。【图解《程序员面试常见的十大算法......
  • 前端(动态雪景背景+动态蝴蝶)
     1.CSS样式<style>html,body,a,div,span,table,tr,td,strong,ul,ol,li,h1,h2,h3,p,input{font-weight:inherit;font-size:inherit;list-style:none;border-spacing:0;border:0;border-collapse:......
  • 【HTML】简单制作一个动态3D正方体
     目录前言开始HTML部分JS部分CSS部分效果图总结前言    无需多言,本文将详细介绍一段代码,具体内容如下: 开始    首先新建文件夹,创建两个文本文档,其中HTML的文件名改为[index.html],JS的文件名改为[script.js],CSS的文件名改为[style.css],创建好后......
  • 【高校科研动态】贵州师大博士生封清为一作在J. Clean. Prod.发文:中国扶贫搬迁对生态
    目录1.文章简介 2.主要研究内容    3.文章引用1.文章简介 论文名称:QuantifyingtheextentofecologicalimpactfromChina'spovertyalleviationrelocationprogram:AcasestudyinGuizhouProvince第一作者及通讯作者:封清(博士研究生),周忠发(教授)第一作......
  • 代码随想录算法训练营三刷day44 | 动态规划之 完全背包 518. 零钱兑换 II 377. 组合总
    三刷day44完全背包基础知识问题描述举个栗子518.零钱兑换II1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组377.组合总和Ⅳ1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例来推导dp......
  • Python 使用matplotlib创建各种静态、动态、交互式和3D图表的功能
    在Python中,你可以使用各种库来创建和显示图表。其中,最常用的库之一是matplotlib,它提供了创建各种静态、动态、交互式和3D图表的功能。另一个流行的库是seaborn,它基于matplotlib,并提供了更高级别的界面,用于绘制有吸引力的统计图形。以下是一个使用matplotlib创建并显示简单折线......