8 篇文章 2 订阅

# 动态规划的定义

int fib(int i)
{
if(i <= 1)
{
return 0;
}
return fib(i - 1) + fib(i - 2);
}

#include <iostream>
#include <stdlib.h>
#include <vector>

using namespace std;

int fib(int n, vector<int>& vec);

int main(int argc, char** argv)
{
if(argc != 2)
{
cout << "usage: ./a.out number" << endl;
}
int num = atoi(argv[1]);

vector<int> vec(num + 1, -1);

int ret = fib(num, vec);

cout << "fib(" << argv[1] << ")" << " = " << ret << endl;
return 0;
}

int fib(int n, vector<int>& vec)
{
if(n <= 1)
{
return 1;
}

if(vec[n] == -1)
{
vec[n] = fib(n - 1, vec) + fib(n - 2, vec);
}
return vec[n];
}

#include <iostream>
#include <stdlib.h>

using namespace std;

int fib(int n);

int main(int argc, char** argv)
{
if(argc != 2)
{
cout << "usage: ./a.out number" << endl;
}

int ret = fib(atoi(argv[1]));
cout << "fib(" << argv[1] << ")" << " = " << ret << endl;
return 0;
}

int fib(int n)
{
if(n <= 1)
{
return 1;
}

int n1 = 1;
int n2 = 1;

for(int i = 1; i < n; ++i)
{
int temp = n1;
n1 = n1 + n2;
n2 = temp;
}

return n1;
}

# 背包问题

01背包问题的描述：有编号分别为a,b,c,d,e的五件物品，它们的重量分别是2,2,6,5,4，它们的价值分别是6,3,5,4,6，现在给你个承重为10的背包，如何让背包里装入的物品具有最大的价值总和？

f[i,j]表示在前i件物品中选择若干件放在承重为 j 的背包中，可以取得的最大价值。
Pi表示第i件物品的价值。

#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


/************************************************************************/
/* 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;

{
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();
return 0;
}

# 参考文献：

03-14
05-13 3万+

04-18
07-06 39万+
04-15 15万+
03-13 1万+
12-26 3万+
08-24 26万+
10-19 2万+
06-11 4987
01-10 1596
10-10 260
02-21 1751
04-25 17万+

oscarwin

¥2 ¥4 ¥6 ¥10 ¥20

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