简单动态规划

4 篇文章 0 订阅
3 篇文章 0 订阅

简单动态规划

简单背包问题 :

假设你要去野营。你有一个容量为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;

}

………

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值