day35.动态规划--代码随想录0-1背包问题

 一.0-1背包问题

小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。他需要带一些研究材料,但是他的行李箱空间有限。这些研究材料包括实验设备、文献资料和实验样本等等,它们各自占据不同的空间,并且具有不同的价值。 

小明的行李空间为 N,问小明应该如何抉择,才能携带最大价值的研究材料,每种研究材料只能选择一次,并且只有选与不选两种选择,不能进行切割。

 思路:我们要直到dp[i][j]代表从下标(0,i)的物品里任意取,放到背包容量为j的背包里,最大价值为dp[i][j],而动态规划问题就是保存局部最优解,确定递推公式:如果当前背包容量小于当前物品的容量,就继承上一个 i-1的值,否则的话,就判断,是i-1的最优解大一些,还是加上当前的物品的价值再加上剩余的dp[i][j]最优解大一些**(难点),取二者较大的值,继续遍历,最后在dp数组的最后就是我们0-1背包问题的最优解。

#include <iostream>
#include <vector>
using namespace std;
int main() {

	int  n,bagweight;//n代表容量 
	cin >> n >> bagweight;//bag代表空间
	
	vector<int> weight(n,0);//物品的重量
	vector<int> value(n, 0);//物品的价值

	for (int i = 0; i < n; i++) {
		cin >> weight[i];
	}
	for (int i = 0; i <n; i++) {
		cin >> value[i];
	}
	vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));//初始化dp数组   二维
	//                    行数   每一行是一个大小为 bagweight + 1 且元素都为 0 的 vector<int>。

	for (int j = weight[0]; j <= bagweight; j++) {
		dp[0][j] = value[0];//n=0时 将最左侧的那一行初始化成0
	}

	for (int i = 1; i < weight.size(); i++) {//遍历物品重量
		for (int j = 0; j <= bagweight; j++) {//包的空间
			if (j < weight[i]) {//如果当前的剩余空间小于物品空间 
				dp[i][j] = dp[i - 1][j];//继承i-1的值
			}
			else {//若可以装下
				dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);//则看一看装进此物品后 与i-1比较谁的价值更大一些
			}															//取最大的存到dp[i][j]中
		}
	}
	cout << dp[n - 1][bagweight] << endl;
}

 416.分割等和子集

给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

 思路:同0-1背包问题很像,但是滚动数组那块没太懂,明天在研究

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int sum=0;

        vector<int> dp(10001,0);
        for(int i=0;i<nums.size();i++){
            sum+=nums[i];
        }
        if (sum % 2 == 1) return false;
        int target = sum / 2;

        for(int i=0;i<nums.size();i++){
            for(int j=target;j>=nums[i];j--){
                dp[j]=max(dp[j],dp[j-nums[i]]+nums[i]);
            }
        }
      if (dp[target] == target) return true;
        return false;
    }
};

二.vector底层实现的原理

1.一句话概括:

底层实现了一个动态的数组。

2.然后咱们先从类的构成出发

class Vector 继承的是我们的Vector base,而 Vector base 有三个重要的元素指针,如下图所示:

 三个指针的位置如下图所示:    

然后的话再说说vector具体的接口实现:

1.无参构造函数: 因为stl容器主要就是以性能优先嘛,所以无参构造就没有申请动态内存            

2.有参构造,一次性申请足够的内存,二者的主要区别如下:

3.vector的插入和删除 :

在插入时要检查空间,看看M_finsh是否等于end_of_storage,若等于要分配空间,分配空间的话要先分配翻倍的空间,然后把原有的元素赋值到新开辟的空间,之后在将原来的空间释放掉。

删除元素的话要注意,删除元素后,元素所对于的空间并没有被删除。 

 4.读取元素+修改元素

5.释放空间: 

shrink_to_fit就是将指针m_finish到m_end_of_storage的内存释放掉

 

 如果想把所有的空间都释放掉,那么要先调用clear() 清空里面所以元素(不会释放内存),

在调用shrink_to_fit去释放内存.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值