首页 > 其他分享 >45. 动态规划

45. 动态规划

时间:2023-07-13 19:13:37浏览次数:40  
标签:背包 int 45 value 装入 1500 物品 动态 规划

一、什么是动态规划

  动态规划(Dynamic Porogramming)是算法的核心是:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法。动态规划与分治算法类似,不同的是,适用于动态规划求解的问题,经分解得到子问题往往不是互相独立的,即下一个子阶段的求解是建立在上一个子阶段的基础上,进行进一步的求解。

二、背包问题

  背包问题主要是指一个给定容量的背包、若干具有一定价值和重量的物品,如何选取物品放入背包是物品的价值最大。其中,又分为 01 背包和完全背包问题。其中,01 背包 指的是每个物品最多放一个,完全背包 指的是每种物品都有无限件可用。完全背包可以转换为 01 背包。

  背包问题解决的主要思想:利用动态规划来解决。每次遍历到的第 i 个物品,根据 w[i] 和 v[i] 来确定是否需要将物品放入背包中。即对于给定的 n 个物品,设 v[i]、w[i] 分别为第 i 个物品的价值和重量,C 为背包的容量。再另 v[i][j] 表示在前 i 个物品中能够装入容量为 j 的背包中的最大价值。则我们有下面的结果:

// 表示填入表第一行和第一列是0
v[i][0] = v[0][j] = 0; 
// 当准备加入新增的商品大于当前背包的容量时,就直接使用上一个单元格的装入策略   
if(w[i] > j)
{
    v[i][j] = v[i-1][j];
}
// 当准备加入的新增的商品容量小于等于当前背包的容量
// 装入的方式:
// v[i-1][j]:就是上一个单元格的装入的最大值
// v[i]:表示当前商品的价值
// v[i-1][j-w[i]]:装入i-1个商品到剩余空间j-w[i]
if(j >= w[i])
{
    v[i][j] = max(v[i-1][j],v[i]+v[i-1][j-w[i]]);
}
物品 重量 价值
吉他(G) 1 1500
音响(S) 4 3000
电脑(L) 3 2000
物品 0 磅 1 磅 2 磅 3 磅 4 磅
0 0 0 0 0
吉他(G) 0 1500(G) 1500(G) 1500(G) 1500(G)
音响(S) 0 1500(G) 1500(G) 1500(G) 3000(G)
电脑(L) 0 1500(G) 1500(G) 2000(G) 2000(L)+ 1500(G)
#include <stdio.h>
#include <string.h>
#include <math.h>

int main(void)
{
    int i = 0,j = 0;
    int weight[] = {1,4,3};                         // 物品的重量
    int value[] = {1500,3000,2000};                 // 物品的价值
    int capacity = 4;                               // 背包的容量
    int count = sizeof(value)/sizeof(value[0]);     // 物品的个数

    // 为了记录放入商品的情况,我们定义一个二维数组
    int path[count+1][capacity+1];
    memset(path,0,sizeof(path));

    // v[i][j]表示前i个物品中能够装入容量为j的背包中的最大价值
    int v[count+1][capacity+1];   
    memset(v,0,sizeof(v));
  
    for(i = 1; i < count+1; i++)                    // 不处理第一行
    {
        for(j = 1; j < capacity+1; j++)             // 不处理第一列
        {
            // 当准备加入新增的商品大于当前背包的容量时,就直接使用上一个单元格的装入策略 
            if(weight[i-1] > j)
            {
                v[i][j] = v[i-1][j];
            }
            // 当准备加入的新增的商品容量小于等于当前背包的容量
            // 装入的方式:
            // v[i-1][j]:就是上一个单元格的装入的最大值
            // value[i]:表示当前商品的价值
            // v[i-1][j-w[i]]:装入i-1个商品到剩余空间j-w[i]
            else
            {
                // v[i][j] = fmax(v[i-1][j],value[i-1]+v[i-1][j-weight[i-1]]);
                // 为了记录商品存放背包的情况,我们不能直接使用上面的公式,需要使用if-else来处理
                if(v[i-1][j] < value[i-1] + v[i-1][j-weight[i-1]])
                {
                    v[i][j] = value[i-1] + v[i-1][j-weight[i-1]];
                    // 把当前的情况记录到path
                    path[i][j] = 1;
                }
                else
                {
                    v[i][j] = v[i-1][j];
                }
            }
        }
    }

    // 输出最终我们放入的是哪些商品
    i = count;                                      // 行的最大下标
    j = capacity;                                   // 列的最大下标
    while(i > 0 && j > 0)
    {
        if(path[i][j] == 1)
        {
            printf("第%d个商品放入到背包!\n",i);
            j -= weight[i-1];
        }
        i--;
    }

    return 0;
}

标签:背包,int,45,value,装入,1500,物品,动态,规划
From: https://www.cnblogs.com/kurome/p/17551823.html

相关文章

  • 2023-07-13 【动态规划】爬楼梯
    题目链接:爬楼梯详细:假设你正在爬楼梯。需要n阶你才能到达楼顶。每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到楼顶呢?示例1:输入:n=2输出:2解释:有两种方法可以爬到楼顶。1阶+1阶2阶示例2:输入:n=3输出:3解释:有三种方法可以爬到楼顶。1阶......
  • 动态规划DP入门笔记
    动态规划以斐波那契数列为例:\(f_i\)状态\(f_i=f_{i-1}+f_{i-2}\)转移方程\(f_0=0\),\(f_1=1\)初始化dp的实现方法一般有三种,其中的两种(最重要的)如下#include<bits/stdc++.h>usingnamespacestd;intf[200010];signedmain(){ intn; scanf("%d",&n);......
  • C#动态编译计算
    示例代码:usingMicrosoft.CSharp;usingSystem;usingSystem.CodeDom.Compiler;usingSystem.Reflection;namespaceConsoleApp6{internalclassProgram{privatestaticvoidMain(string[]args){Expressione=newExpress......
  • C语言动态分配内存的函数
    今天在学习中碰见了动态分配内存有关的函数:mallocrealloccallocfree。以下是详细的记录"动态内存":在程序运行期间,动态分配内存空间,一般是在"堆,heap"空间上分配。malloc:memoryallocate内存分配realloc:repeatallocate再分配——重新分配:一次内存分配完成之后,后面用......
  • MyBatis动态表名和字段,减轻很大工作
    在动态sql解析过程,#{}与${}有本质差别1.#{}是基于JDBC的preparedStaement,${}是基于JDBC的Statement2.#{}表示的是预编译的参数,就是替代在SQL语句中的占位符‘?’,并会将参数作为字符串处理;如果要动态传入表名或者字段名,不能使用#{}3.#{}是使用预编译传参,可以预防SQL......
  • CF1456E XOR-ranges
    题面传送门好题。首先比较自然的,相当于按照数位DP的方法,将\([l,r]\)剖成\(k\)段,其中每一段都是最高若干位确定,底下若干位任取的形式。这样在\([l,r]\)里面选择相当于在这\(O(k)\)个区间里面选择。然后假设我们依次选择好了,考虑如何计算答案。答案显然是位独立的,对于......
  • 高性能网络SIG月度动态:virtio-net 支持动态中断调节,SMC v2 协议增加新扩展
    高性能网络SIG(SpecialInterestGroup):在云计算时代,软硬件高速发展,云原生、微服务等新的应用形态兴起,让更多的数据在进程之间流动,而网络则成为了这些数据流的载体,在整个云时代扮演者前所未有的重要角色。在这个万物互联的时代,云上的网络通信效率对各种服务至关重要,高性能网......
  • P1115 最大子段和 一维动态规划
    #include<iostream>#include<cmath>usingnamespacestd;longlongn,a[200005],dp[200005],ans;intmain(){cin>>n;for(inti=1;i<=n;i++){cin>>a[i];}dp[1]=a[1];ans=a[1];for(inti=2;i<......
  • CF1450C2 题解
    题目传送门再不写题解社贡要掉到\(0\)了。题目分析显然如果\(3\)个格子构成了满足获胜条件的情况,这\(3\)个格子模\(3\)的余数各不相同。那么我们将格子按模\(3\)的余数分为\(3\)类,只要保证相邻\(3\)个格子中有\(2\)个不同就行了,不需要动第\(3\)个。我们令......
  • Leetcode - 动态规划总结(必看!!!)
     一、labuladong动态规划模板思路wiki:https://labuladong.gitee.io/algo/di-ling-zh-bfe1b/dong-tai-g-1e688/题目: 动态规划模板思路: 二、我自己如何理解【状态】【选择】 以714题目《最佳时机去买卖股票+手续费》为例子:1.确定【状态】--寻找原问题和子问题中,......