C++ vector的用法(整理)
vector 是向量类型,它可以容纳许多类型的数据,如若干个整数,所以称其为容器。vector 是C++ STL的一个重要成员,使用它时需要包含头文件:
#include;
一、vector 的初始化:可以有五种方式,举例说明如下:
(1) vector<int> a(10); //定义了10个整型元素的向量(尖括号中为元素类型名,它可以是任何合法的数据类型),但没有给出初值,其值是不确定的。
(2)vector a(10,1); //定义了10个整型元素的向量,且给出每个元素的初值为1
(3)vector a(b); //用b向量来创建a向量,整体复制性赋值
(4)vector a(b.begin(),b.begin+3); //定义了a值为b中第0个到第2个(共3个)元素
(5)int b[7]={1,2,3,4,5,9,8};
vector a(b,b+7); //从数组中获得初值
1)向向量a中添加元素
1、
1 vector a;
2 for(int i=0;i<10;i++)
3 a.push_back(i);
背包问题
01背包问题的描述:有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
要从5个中选出若干个装入容量为10的背包,可以分解为,将a物品装入背包,然后从其他四个中选出若干个装入剩余容量为8的袋子,因为a已经占去了2个位置;或者不装a,从其他四个中选出若干个装入容量为10的袋子?这两种做法中,价值最大的就是我们需要的方案。如果选择了第一种方案,那么继续分解,将b物品装入袋子,从其余三个中选出若干个装入剩余容量为6的袋子,或者不装b(也许你更乐意装b),从剩余三个中选出若干个装入剩余容量为8的袋子,选择这两种方案中价值最大的。依次类推,直到五个物品都选择完毕。将其一般化,用i代替a,用j代替10,用数学公式表达出来就是上面那个公式了,是不是觉得已经看懂了这个公式。
上面公式中还有个( j >= Wi ),表示剩余的容量至少要大于该物品的重量,才需要讨论装不装的问题。
既然子问题已经解决,那么自然想到用递归了,我们用递归来实现
#include <iostream>
#include <vector>
using namespace std;
vector<char> things = {'a', 'b', 'c', 'd', 'e'};
vector<int> value = {6, 3, 5, 4, 6};
vector<int> weight = {2, 2, 6, 5, 4};
int backpack(int n, int w)
{
if(n == 0 | w == 0)
{
return 0;
}
int ret;
if(w < weight[5 - n])
{
ret = backpack(n - 1, w);
cout << "n = " << n << " w = " << w << " val = " << ret << endl;
return ret;
}
//n表示从多少件物品中选
//刚开始可以从五件物品中选,然后就是两种情况,放入第一件还是不放入第一件
//第一件选择完毕后,就需要从其余四件中选择,重复上面的过程
//
//当n=5时,5-n表示第一件,n=4时候,5-n表示第二件
int val1 = backpack(n - 1, w - weight[5 - n]) + value[5 - n];
int val2 = backpack(n - 1, w);
if(val1 > val2)
{
ret = val1;
//cout << "选择物品" << things[5 - n] << endl;
}
else if(val1 < val2)
{
ret = val2;
//cout << "不选择物品" << things[5 - n] << endl;
}
else
{
ret = val1;
//cout << "拿不拿" << things[5 - n] << "一样" << endl;
}
cout << "n = " << n << " w = " << w << " val = " << ret << endl;
return ret;
}
int main()
{
int ret = backpack(5, 10);
cout << "max value = " << ret << endl;
return 0;
}
//输出结果
n = 1 w = 1 val = 0
n = 1 w = 6 val = 6
n = 2 w = 6 val = 6
n = 3 w = 6 val = 6
n = 1 w = 2 val = 0
n = 2 w = 2 val = 0
n = 1 w = 3 val = 0
n = 1 w = 8 val = 6
n = 2 w = 8 val = 6
n = 3 w = 8 val = 6
n = 4 w = 8 val = 9
n = 1 w = 2 val = 0
n = 2 w = 2 val = 0
n = 1 w = 3 val = 0
n = 1 w = 8 val = 6
n = 2 w = 8 val = 6
n = 3 w = 8 val = 6
n = 1 w = 4 val = 6
n = 2 w = 4 val = 6
n = 1 w = 5 val = 6
n = 1 w = 10 val = 6
n = 2 w = 10 val = 10
n = 3 w = 10 val = 11
n = 4 w = 10 val = 11
n = 5 w = 10 val = 15
max value = 15
同样出现与求斐波那契数列相同的问题,有重复计算的地方。同样的,采取用数组来保存结果,这个结果就是上面那个表,显然我们要用一个二维数组才能完成该工作。可以采取,与之前相同的方法,在递归里加数组,但是这次我们换一种方式,用循环来做。
为了便于描述,用e2单元格表示e行2列的单元格,这个单元格的意义是用来表示只有物品e可以选择了,有个承重为2的背包,那么这个背包的最大价值是0,因为e物品的重量是4,背包装不了。对于d2单元格,表示只有物品e,d可以选择时,承重为2的背包,所能装入的最大价值,仍然是0,因为物品e,d都不是这个背包能装的。所以这个表列上的数字表示背包目前的容量,该行以及该行以下的物品是可以选择的,而该行以上的物品则不是该行可以选择的。这个表是从下往上、从左往右生成的。
以第4列为例分析一下生成过程:e4用公式表示就是f[1, 4] = max{(f[0, 4 - 4] + 6), f[0, 4]},对于d4用公式表示就是f[2, 4] = max{f[1, 4]}(因为容量为4的背包装不下重量为5的d物体),同理c4=f[3, 4]=max{f[2, 4]},b4 = f[4, 4] = max{(f[3, 4 - 2] + 3), f[3, 4]}
/************************************************************************/
/* 01背包问题
** 问题描述:有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
/************************************************************************/
#include <tchar.h>
#include <iostream>
#include <vector>
#include <string.h>
#include <cstdlib>
using namespace std;
int weight[5] = {2, 2, 6, 5, 4}; //每个物品的重量
int value[5] = {6, 3, 5, 4, 6}; //每个物品的价值
int C[6][11]; //保存各种情况能装下物品价值的数组
vector<int> path;
void FindAnswer()
{
int capacity = 10;
for (int i = 5; i > 0; --i)
{
if (C[i][capacity] > C[i - 1][capacity])
{
path.push_back(i);
capacity -= weight[i - 1];
}
}
}
void Package()
{
for (int i = 0; i < 11; i++)
{
for (int j = 0; j <6; ++j)
{
if (i == 0)
{
//可选物品为0,所以能装的价值只能为0
C[j][i] = 0;
}
else if (j == 0)
{
//容量为零,所以能装的价值也是0
C[j][i] = 0;
}
else
{
//判断当前容量能放入
if (i >= weight[j - 1])
{
C[j][i] = max(C[j - 1][i], (C[j -1][i - weight[j - 1]] + value[j - 1]) );
}
//如果不能放入,则不放入该物品
else
{
C[j][i] = C[j - 1][i];
}
}
}
}
}
int _tmain(int args, TCHAR* argv[])
{
memset(C, -1, sizeof(C));
Package();
FindAnswer();
return 0;
}
原文链接:https://blog.csdn.net/shanghairuoxiao/article/details/62426727