递推,记忆化搜索,分治(7)

一、递推算法

1.1 简介

递推算法大家肯定都很熟悉。它和递归算法名字相近,但它们有所不同:递推算法它运行效率高,而且代码量还少;但是递归算法的代码较多,它的效率也不怎么高,可能会“Time Limit Exceeded”,一不小心还有可能爆栈(Memory Limit Exceeded)。

1.2 方法

1.2.1 顺推法

从已知的条件出发,逐步推算出要解决的方法(数学公式)。

1.2.2 逆推法

从结果出发,用迭代法推算出问题开始的答案(数学公式)。

*两种方法的实现方法相似,但思路不同

1.3 例题&代码

题目

数塔问题

如图所示为一个数字三角形,请编程计算从顶到底的某处的一条路径,使该路径经过的数字总和最大,只要求输出总和。
递推,记忆化搜索,分治(7)_第1张图片

输入格式

第1行,输入一个正整数n;第2行到第n+1行,输入一个三角形。

输出格式

输出一个数,代表最大路径组合。

样例输入

5
7
3 8
8 0 1
2 7 4 4
4 5 2 6 5

样例输出

30

数据规模与约定

保证所有数据:
0

---------------------------------------------------------------------------------------------------------------------------

代码

1.顺推法

#include
using namespace std;
int a[101][101];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			cin>>a[i][j];
		}
	}
	for(int i=n-1;i>=1;i--)
	{
		for(int j=1;j<=i;j++)
		{
			a[i][j]+=max(a[i+1][j],a[i+1][j+1]);
		}
	}
	cout<<a[1][1];
	return 0;
}

代码说明:从n-2行开始,依次向上计算每个数的第i-1行所对应的两个数(i+1,j 和 i+1,j+1)相加的和。


2.逆推法

#include
using namespace std;
int a[101][101],maxn;
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			cin>>a[i][j];
 		}
    }
 	for(int i=2;i<=n;i++)
    {
  		for(int j=1;j<=i;j++)
  		{
   			a[i][j]+=max(a[i-1][j],a[i-1][j-1]);
  		}
 	}
 	for(int i=1;i<=n;i++)
  	maxn=max(maxn,a[n][i]);
 	cout<<maxn;
	return 0;
}

代码说明:从2行开始,依次向下计算每个数的第i+1行所对应的两个数(i-1,j 和 i-1,j-1)相加的和。

二、记忆化搜索

2.1 简介

记忆化搜索算法中综合运用了两个知识点:递归递推。这种方法用起来比较方便(我觉得没有递推方便,嘻嘻!)。

2.2 常见题目

上楼梯

一个含有n阶的楼梯,一次可以走1阶或2阶,从底走到顶一共有几种走法?
(n<=90)

拍卖

一般情况下,拍卖行的拍卖师在拍卖商品的时候都是从低价开始起拍,由买方报价,最后谁出的价格高,商品就归谁所有。但有个拍卖行,拍卖师在拍卖商品时正好相反:总是从高价开始起拍,如果没有人举成交牌就降价,而且拍卖师在降价时还有规律:假如第i次报价为w元,那么第i+1次报价为w-a或者w-b元,如果降到p元时,你认为价格合适,赶快第一个举成交牌,你就花p元买下了商品。
任务:拍卖师把商品从w元降到p元的方法总数。

代码

1.上楼梯

递推,记忆化搜索,分治(7)_第2张图片

2.拍卖

递推,记忆化搜索,分治(7)_第3张图片

三、分治

3.1 简介

在我还没有开始学的时候,总觉得算法是一个及其高级的玩意儿,有种不敢碰它的感觉(包括 分治算法 在内)。可是学了之后。。。这也没有什么special的。

分治算法顾名思义就是分而治之的意思。主体思想呢就是把一件大的事情分开来做(计算)。其实,就和小学学的数学广角——找次品问题雷同。比如:

一共有8枚硬币,其中有一枚硬币是假币。现在用天平称,最少称多少次把假币找出?

*这道题就是先把天平的美易边放上4枚硬币,称出假币在哪4枚中。再把这4枚分成2枚2枚的,继续称。接着找到有假币的那一边,继续称最后就能找到。
在分治算法中最常见的方法是二分法二分法可以运用在许多程序中,比如:归并排序 等等。

3.2 例题&代码

题目

桐桐查单词

今天桐桐接到一个任务,就是把一篇英语文章翻译成中文。对桐桐来说,这任务实在太艰巨了,可怜的桐桐只好拿着英文字典一句句慢慢翻译起来。希望桐桐能在规定的时间内完成任务吧。

输入格式

第1行一个整数n,表示字典中一共有多少单词。
接下来每两行表示一个单词,其中:
第1行是长度<=100的字符串,表示这个单词,全部字母小写,单词不会重复。
第2行是一个整数,表示这个单词在字典中的页码。
接下来一行是一个整数m,表示要查单词数。
接下来m行,每行一个字符串,表示要查的单词,保证在字典中存在。

输出格式

m行,每行一个整数,表示i个单词在字典中的页数。

样例输入

2
scan
10
word
15
2
scan
word

输出格式

10
15

数据规模与约定

全部数据保证:
n<=20000
m<=10000

---------------------------------------------------------------------------------------------------------------------------

代码

递推,记忆化搜索,分治(7)_第4张图片
递推,记忆化搜索,分治(7)_第5张图片

THE END

好了,今天就说到这儿吧(毕竟我才学到这儿呀,嘿嘿嘿)
今天我是第一次写博客,如写得不好,敬请理解!!!
如果觉得我写的有用,请多留意我日后的博客。

*题目均来自JZOJ网站(39.98.198.136),照片均来自老师PPT

你可能感兴趣的:(C++,算法,心得)