简单动态规划
简单背包问题 :
假设你要去野营。你有一个容量为6磅的背包,需要决定该携带下面的哪些东西。其中
每样东西都有相应的价值,价值越大意味着越重要:
1 水(重3磅,价值10);
2 书(重1磅,价值3);
3 食物(重2磅,价值9);
4 夹克(重2磅,价值5);
5 相机(重1磅,价值6)。
请问携带哪些东西时价值最高?
算法思想:
两部分:
第一部分: 细分背包,将背包从最小单元逐渐增加满包。
第二部分: 增加物品,将物品个数从单一逐渐增加到全部。
第一部分:
主要是分析背包所能有的大小下的各种情况,最终去最好的。
第二部分:
主要是处理当新物品加入时,是否放得下。
当能放下时更新。(更新方式取决于,剩余空间+剩余物品 )
(即:此物品未加入时的情况下,在这个物品加入后还剩下的空间中最好的选择)
算法代码:
时间 O( n*m) 空间 ( n *m)
#include<iostream>
using namespace std;
/*
假设你要去野营。你有一个容量为6磅的背包,需要决定该携带下面的哪些东西。其中
每样东西都有相应的价值,价值越大意味着越重要:
? 水(重3磅,价值10);
? 书(重1磅,价值3);
? 食物(重2磅,价值9);
? 夹克(重2磅,价值5);
? 相机(重1磅,价值6)。
请问携带哪些东西时价值最高?
*/
//返回a,b中大者
int max(int a, int b)
{
return a >= b ? a : b;
}
int main()
{
//物品价值
int val[5] = { 10,3,9,5,6 };
//物品重量
int weight[5] = { 3,1,2,2,1 };
//物品名字
string name[5] = { "水","书","食物","夹克","相机" };
//规划价值
int maxval[6][7] = { 0 };
//规划选择
string maxselect[6][7];
//的循环 物品数逐渐增加
for (int i = 1; i < 6; ++i)
{
//背包大小逐渐增加
for (int j = 1; j < 7; ++j)
{
//更新规划
maxval[i][j] = max(maxval[i - 1][j], (weight[i - 1] <= j ? val[i - 1] + maxval[i - 1][j - weight[i - 1]] : maxval[i - 1][j]));
maxselect[i][j] = maxval[i][j] == maxval[i - 1][j] ? maxselect[i - 1][j] : name[i - 1] + " " + maxselect[i - 1][j - weight[i - 1]];
}
}
//打印最终结果
cout << "最优选择:" << maxselect[5][6] << endl<< "最大价值:" << maxval[5][6] << endl;
return 0;
}
……
最大公共子串:
求两个单词的最长公共字串 列 : fish files
算法思想:
网格划分 行为单词a,列为单词b
分两部分:1.逐渐增加单词a b 2.更新子串长度
1.分别细分a,b单词 逐渐增加长度 直至单词完整
2.在逐渐完整的过程中,比较单词字母是否相等
当相等,则更新他的子串长度为其前一个顺位子串长度+1
不相等,则初始为0
算法代码:
时间 O( n*m) 空间 (n *m)
#include<iostream>
using namespace std;
/*求两个单词的最长公共字串 列 : fish hish */
int main()
{
string a, b;
cout << "输入两个单词" << endl;
cin >> a >> b;
//动态规划数组 默认大小不超过100
int vmax[100][100] = { 0 };
//最大子串长度
int maxlen = 0;
//a单词
for (int i = 1; i < a.size() + 1; ++i)
{
//b单词
for (int j = 1; j < b.size() + 1; ++j)
{
//比较
if (a[i - 1] == b[j - 1])
{
//更新字串长度
vmax[i][j] = vmax[i - 1][j - 1] + 1;
//更新最大子串长度
if (vmax[i][j] > maxlen)
maxlen = vmax[i][j];
}
else
{
vmax[i][j] = 0;
}
}
}
cout << "最大公共子串为:" << maxlen;
return 0;
}
………