首页 > 其他分享 >动态规划(2)

动态规划(2)

时间:2024-01-17 12:33:06浏览次数:24  
标签:weight nums int sum vector 动态 规划 dp

目录

01背包

二维数组

注意:

  1. 初始化
  2. 遍历顺序
//二维dp数组实现
#include <bits/stdc++.h>
using namespace std;

int n, bagweight;// bagweight代表行李箱空间
void solve() {
    vector<int> weight(n, 0); // 存储每件物品所占空间
    vector<int> value(n, 0);  // 存储每件物品价值
    for(int i = 0; i < n; ++i) {
        cin >> weight[i];
    }
    for(int j = 0; j < n; ++j) {
        cin >> value[j];
    }
    // dp数组, dp[i][j]代表行李箱空间为j的情况下,从下标为[0, i]的物品里面任意取,能达到的最大价值
    vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));

    // 初始化, 因为需要用到dp[i - 1]的值
    // j < weight[0]已在上方被初始化为0
    // j >= weight[0]的值就初始化为value[0]
    for (int j = weight[0]; j <= bagweight; j++) {
        dp[0][j] = value[0];
    }

    for(int i = 1; i < weight.size(); i++) { // 遍历科研物品
        for(int j = 0; j <= bagweight; j++) { // 遍历行李箱容量
            // 如果装不下这个物品,那么就继承dp[i - 1][j]的值
            if (j < weight[i]) dp[i][j] = dp[i - 1][j];
            // 如果能装下,就将值更新为 不装这个物品的最大值 和 装这个物品的最大值 中的 最大值
            // 装这个物品的最大值由容量为j - weight[i]的包任意放入序号为[0, i - 1]的最大值 + 该物品的价值构成
            else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
        }
    }
    cout << dp[weight.size() - 1][bagweight] << endl;
}

int main() {
    while(cin >> n >> bagweight) {
        solve();
    }
    return 0;
}

滚动数组

从后向前遍历,不能让上一个状态影响到当前状态

void test_1_wei_bag_problem() {
    vector<int> weight = {1, 3, 4};
    vector<int> value = {15, 20, 30};
    int bagWeight = 4;

    // 初始化
    vector<int> dp(bagWeight + 1, 0);
    for(int i = 0; i < weight.size(); i++) { // 遍历物品
        for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量
            dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
        }
    }
    cout << dp[bagWeight] << endl;
}

int main() {
    test_1_wei_bag_problem();
}

416分割等和子集

如何转化当前问题为01背包呢?
我们设计一个背包,能存储的最大数量为nums的sum的一半,如果能存满,就说明能分割出一个等和的子集

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int n=nums.size();
        int sum=0;
        for(int i=0;i<n;i++)
        {
            sum+=nums[i];
        }
        if(sum%2==1)
        {
            return false;
        }
        int bag=sum/2;
        vector<int> dp(bag+1,0);
        for(int i=0;i<n;i++)
        {
            for(int j=bag;j>=nums[i];j--)
            {
                dp[j]=max(dp[j],dp[j-nums[i]]+nums[i]);
            }
        }
        if(dp[bag]==bag)
        {
            return true;
        }
        return false;

    }
};

1049最后一块石头的重量

和上一题类似,求出石头一半重量的最大值,再用sum-2*最大值,得到的结果就是剩下的石头的重量

class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        int n=stones.size();
        int sum=0;
        for(int i=0;i<n;i++)
        {
            sum+=stones[i];
        }
        int bag=sum/2;
        vector<int> dp(bag+1,0);
        for(int i=0;i<n;i++)
        {
            for(int j=bag;j>=stones[i];j--)
            {
                dp[j]=max(dp[j],dp[j-stones[i]]+stones[i]);
            }
        }
        return sum-dp[bag]*2;

    }
};

494目标和

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int target) {
        /*如何转换问题为dp?
        nums有一个总和,就拿用例来讲:
        sum=5,target=3,
        也就是我们需要找到凑出1的不同方法
        sum-2*1=3
        dp数组含义:填满空间为j的背包,有dp[j]种方法

        递推思路:凑整dp[5]有多少方法呢,假设当前dp[3]已知,nums[i]==2
        那么当前dp[5]中必然有dp[3]=dp[5-nums[i]]
        也就是把 所有的 dp[j - nums[i]] 累加起来
        递推公式:dp[j]=dp[j]+dp[j-nums[i]]

        初始化:dp[0]=1
        */
        int sum=0;
        int n=nums.size();
        for(int i=0;i<n;i++)
        {
            sum+=nums[i];
        }
        int find2=sum-target;
        if(find2%2==1||find2<0)
        {
            return 0;
        }
        int findval=find2/2;
        vector<int> dp(findval+1,0);
        dp[0]=1;
        for(int i=0;i<n;i++)
        {
            for(int j=findval;j>=nums[i];j--)
            {
                dp[j]=dp[j]+dp[j-nums[i]];
            }
        }

        return dp[findval];
    }
};

标签:weight,nums,int,sum,vector,动态,规划,dp
From: https://www.cnblogs.com/liviayu/p/17969757

相关文章

  • 数据展现之道:精心打造可在线浏览的动态数据报表
    前言如今各类BI产品大行其道,“数据可视化”成为一个热门词汇。相比价格高昂的各种BI软件,用Excel来制作动态报表就更加经济便捷。今天小编就将为大家介绍一下如何使用葡萄城公司的纯前端表格控件——SpreadJS来实现一个Excel动态报表:实现步骤1.在原始数据的基础上生成数据透视表......
  • Java动态代理、AOP和装饰器模式
    面向切面编程AOP-AspectOrientedPrograming,主要用于处理核心业务逻辑外的一些东西,比如日志和缓存。这个“切面”可以理解为在代码的某个地方切一刀,在其中加一些东西。装饰器以日志为例,如果没有使用AOP,那么可以使用装饰来实现类似的代码。我们使用装饰器模式来实现一下在执行......
  • C99标准前后对于二维数组的动态声明问题
    html:toc:true写在前面:出于作者不了解C99以前标准中对二维数组的动态声明而导致的一场考场事故,作者写下这篇文章,,以便其他同学在遇到类似问题时不要犯同样的错误,同时作为对自己的警醒.本文主要是关于对于二维数组动态声明问题在不同C标准下方法的探讨,将给出一个简......
  • 方法论:仓储物流规划--数据分析(转)
     老K-LaoK专栏同名微信公众号:智能仓储物流技术研习社。​关注他 8人赞同了该文章导语大家好,我是智能仓储物流技术研习社的社长,你的老朋友,老K。知识星球 * 原创电子书 * 深海社区 * 微信群文:尹军琪在做物流规划设计时,人们往往对设计指标......
  • 聊聊如何实现动态加载spring拦截器
    前言之前写过一篇文章聊聊如何实现热插拔AOP,今天我们继续整一个类似的话题,聊聊如何实现spring拦截器的动态加载实现核心思路groovy热加载java+事件监听变更拦截器实现步骤1、在项目的pom引入groovyGAV<dependency><groupId>org.codehaus.groovy</groupI......
  • 动态规划(2)
    目录63不同路径2343整数拆分9663不同路径2遇到障碍,说明该点无法到达,那么dp[i][j]=0classSolution{public:intslnA(vector<vector<int>>&obstacleGrid){intm=obstacleGrid.size();intn=obstacleGrid[0].size();vector<vector<int&g......
  • 山海鲸如何实现动态天气
    1.预设雨雪效果雨雪效果中的雨雪大小和雨雪覆盖如果不需要绑定数据,可以先预设好,这样后续切换后就可以有预设的大小,比如我们先将下雪的雪面覆盖设置成0.5。 设置完之后我们把天气设置为无。2.生成数据字段山海鲸中所有的组件属性都可以绑定动态数据,天气属性也不例外,首先我们......
  • 动态规划(1)
    目录动规基础509斐波那契数列746使用最小花费爬楼梯62不同路径写在前面,第二次刷动规,上次就有点没弄懂这次一定拿下了动规基础铭记动规五部曲:确定dp数组(dptable)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组509斐波那契数列classSolution{......
  • 如何使用Java在Excel中添加动态数组公式?
    本文由葡萄城技术团队发布。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。前言动态数组公式是Excel引入的一项重要功能,它将Excel分为两种风格:Excel365和传统Excel(2019或更早版本)。动态数组功能允许用户从单个单元格中的公式......
  • 数学建模入门笔记(1)——Python pulp库解线性规划问题
    参考:Python求解线性规划——PuLP使用教程-Only(AR)-博客园(cnblogs.com)1.Definethemodelmodel=pl.LpProblem(name="",sense=pl.LpMaximize)name模型的名字sense模型的类型(pl.LpMaximize/pl.LpMinimize)2.Definethedecisionvariables用x[i]存储变量,命名为xi......