当前位置: 首页 > news >正文

笔记:代码随想录算法训练营day37:完全背包、518. 零钱兑换 II、377. 组合总和 Ⅳ、70. 爬楼梯 (进阶)

学习资料:代码随想录

文中含大模型生成内容

完全背包

52. 携带研究材料(第七期模拟笔试)

相比于之前的一个物品只能放一次,这次一个物品可以放多次了

递推公式变成了dp[i][j] = max(dp[i - 1][j], dp[i][j - weight[i]] + value[i]);在计算不放该物品有几种方法时,只把该物品的空间让开就可以了

这是二维,先遍历背包还是物品都行

#include <iostream>
#include <vector>
using namespace std;
 
 
int main(){
int n,v;
cin>>n>>v;
 
vector<int> weight(n,0);
vector<int> value(n,0);
 
for(int i=0;i<n;i++){
    cin>>weight[i]>>value[i];
}
 
vector<vector<int>> dp(n,vector<int>(v+1,0));
 
for(int j=value[0];j<=v;j++){
    dp[0][j] = ((j/weight[0])*value[0]);
}
 
for(int i=1;i<n;i++){
    for(int j=0;j<=v;j++){
        if(j<weight[i]) dp[i][j] = dp[i-1][j];
        else{
        dp[i][j] = max(dp[i-1][j],dp[i][j-weight[i]]+value[i]);
        }
    }
}
cout<<dp[n-1][v]<<endl;
return 0;
}

压缩到一维直接借用代码随想录的回答:

将上一层dp[i-1] 的那一层拷贝到 当前层 dp[i] ,那么 递推公式由:dp[i][j] = max(dp[i - 1][j], dp[i][j - weight[i]] + value[i]) 变成: dp[i][j] = max(dp[i][j], dp[i][j - weight[i]] + value[i])

这里有录友想,这样拷贝的话, dp[i - 1][j] 的数值会不会 覆盖了 dp[i][j] 的数值呢?

并不会,因为 当前层 dp[i][j] 是空的,是没有计算过的。

变成 dp[i][j] = max(dp[i][j], dp[i][j - weight[i]] + value[i]) 我们压缩成一维dp数组,去掉 i 层数维度。

即该点还没计算,仍是上一层的值

这道题求价值,对于一维先遍历谁也是无所谓的。

但是,无论二维还是一维,j倒序遍历不行,因为要用到本层的j了。(这里我没模拟,但感觉应该是对的)

一维:

#include <iostream>
#include <vector>
using namespace std;
 
 
int main(){
int n,v;
cin>>n>>v;
 
vector<int> weight(n,0);
vector<int> value(n,0);
 
for(int i=0;i<n;i++){
    cin>>weight[i]>>value[i];
}
 
vector<int> dp(v+1,0);
 
for(int i=0;i<n;i++){
    for(int j=0;j<=v;j++){
        if(j>=weight[i]){
        dp[j] = max(dp[j],dp[j-weight[i]]+value[i]);
        }
    }
}
cout<<dp[v]<<endl;
return 0;
}

518.零钱兑换II

力扣题目链接

求有几种方法

class Solution {
public:
    int change(int amount, vector<int>& coins) {
        // 定义
        vector<vector<uint64_t>> dp(coins.size(),vector<uint64_t>(amount+1,0));
        // 初始化
        for(int i=0;i<coins.size();i++){      //遇到重定义的报错先排查一下是不是i后面写的逗号
            dp[i][0] = 1;
        }
        for(int j=coins[0];j<=amount;j++){
            if(j%coins[0]==0) dp[0][j] = 1;      
        }
        // 遍历
        for(int i =1;i<coins.size();i++){
            for(int j=1;j<=amount;j++){
                if(j<coins[i]) dp[i][j] = dp[i-1][j];
                else{
                    dp[i][j] = dp[i-1][j]+dp[i][j-coins[i]];
                }
            }
        }
        return dp[coins.size()-1][amount];      
    }
};

对于一维,就只能先遍历物品了。为什么二维可以先遍历背包而一维不行?j-coins可能会被覆盖掉,举例coin=1,2,amount=3,根据递推公式dp[j]+=dp[j-coins[i]]和dp[i][j]=dp[i-1][j]+dp[i][j-coins[i]]对比来看,外层是j,一维在物品0时用的j-coins[i]是处理过其他物品后的dp值

class Solution {
public:
    int change(int amount, vector<int>& coins) {
        // 定义
        vector<uint64_t> dp(amount+1,0);
        // 初始化
        for(int j=0;j<=amount;j++){
            if(j%coins[0]==0) dp[j] = 1;      
        }
        // dp[0] = 1;
        // 遍历
        for(int i =1;i<coins.size();i++){
            for(int j=0;j<=amount;j++){
                if(j>=coins[i]){
                    dp[j] = dp[j]+dp[j-coins[i]];
                }
            }
        }
        return dp[amount];      
    }
};

377. 组合总和 Ⅳ

力扣题目链接

求的是排列数,这时就是一维先遍历背包求得的了,让它帮我模拟一下:

感觉这里就暂时摒弃和求组合的方法的比较,单纯从求排列的角度去理解更清晰

class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        vector<uint64_t> dp(target+1,0);

        dp[0] = 1;
        
        for(int j=0;j<=target;j++){
            for(int i =0;i<nums.size();i++){
                if(j>=nums[i]) dp[j]=dp[j]+dp[j-nums[i]];
            }
        } 

        return dp[target];
    }
};

70. 爬楼梯(进阶版)

卡码网:57. 爬楼梯

相当于求的还是方法数

物品重量就是台阶数

#include <iostream>
#include <vector>
 
using namespace std;
 
int main(){
 
int n,m;
cin>>n>>m;
 
vector<int> dp(n+1,0);
 
dp[0]=1;
for(int j=0;j<=n;j++){
    for(int i=1;i<=m;i++){
        if(j>=i) dp[j] +=dp[j-i]; 
    }
}
 
cout<<dp[n];
 
return 0;
}

相关文章:

  • Python--网络编程(下)
  • GPTQ - 生成式预训练 Transformer 的精确训练后压缩
  • C++编程指南23 - 在无关线程之间共享资源时应使用shared_ptr
  • IntelliJ IDEA 华为云远程开发配置步骤
  • 通用文件模型
  • Axure设计之数据列表动态列设置/列筛选案例
  • 设计模式Python版 状态模式
  • 开发者社区测试报告(功能测试+性能测试)
  • 尚硅谷爬虫note14
  • ZooKeeper 基本概述
  • 意向锁的目的
  • 探索数据仓库自动化:ETL流程设计与实践
  • 【Pandas】pandas Series swaplevel
  • Python爬虫实战:一键采集电商数据,掌握市场动态!
  • 自然语言处理(NLP)中文文本预处理主流方法
  • python中采用opencv作常规的图片处理的方法~~~
  • 华为OD机试-发现新词的数量(Java 2024 E卷 100分)
  • Kafka 消息不丢失:全方位保障策略
  • redis菜鸟教程
  • 【MATLAB源码-第271期】基于matlab的雷达发射回波模拟,包括匹配滤波,加窗旁瓣控制,以及MTD处理。
  • 唐山建设集团下岗职工网站/营销型网站建设实训总结
  • 哪些网站可以免费做推广呢/域名注册网站查询
  • 凡客优品官方网站/seo短期培训班
  • 美国哪个网站做diy电脑/seo排名是什么
  • 自己做的网站如何让百度收录/南宁百度seo推广
  • 建设自己的网站首页/怎么把广告发到各大平台