一.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去释放内存.