欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hdu oj 2018 母牛的故事(暴力递归,记忆化搜索,动态规划)

程序员文章站 2022-05-12 15:56:31
...

思路分析:
注:有点绕,建议把n假设为一个确定的数再去理解,比如n=5。
1.老母牛能下崽,因为 (第n年母牛数)=(n-1年母牛数)+ (第n年新出生的母牛数)。
2.第n年新出生的母牛数又等于第n年的老母牛数,所以要求第n年的母牛数目,必须知道n-1年的母牛数目和第n年的老母牛数目。
3.因为4年时间小母牛就变成老母牛,所以
(第n年的老母牛数目) = (第n-3年的老母牛数目) + (第n-3年的小母牛数) = 第n-3年母牛总数。


1.通过以上分析,可以得到暴力递归的表达式: n>4时,count[n] = count[n-1] + count[n-3] 。

#include<iostream>
using namespace std;

int cowCount(int year) {
	
	if (year < 5)
		return year;
	return cowCount(year - 1) + cowCount(year - 3);
}

int main()
{
	int year;

	while (cin >> year && year > 0)
		cout << cowCount(year) << endl;

	return 0;
}


2.记忆化搜索:将已经计算过的数据保存好,以后直接使用,不再重复调用递归

#include<iostream>
#include<vector>
using namespace std;

vector<int> mem;
int cowCount_two(int year) {
	
	if (year < 5)
		return year;
	if (mem[year] != -1)             //已经计算过,直接返回
		return mem[year];
	else 
		mem[year]= cowCount_two(year - 1) + cowCount_two(year - 3);    //没有计算过,递归调用计算,并保存计算的结果(记忆)
	return mem[year];
}

int cowCount(int year) {

	mem = vector<int>(year + 1, -1);
	return cowCount_two(year);
}

int main()
{
	int year;

	while (cin >> year && year > 0)
		cout << cowCount(year) << endl;

	return 0;
}


3.动态规划:迭代完成

#include<iostream>
#include<vector>
using namespace std;

vector<int> mem;

int cowCount_three(int year) {

	if (year < 5)      //避免mem下标赋值越界
		return year;
	mem[1] = 1;
	mem[2] = 2;
	mem[3] = 3;
	mem[4] = 4;
	for (int i = 5; i <= year; i++)
		mem[i] = mem[i - 1] + mem[i - 3];
	return mem[year];
}

int cowCount(int year) {

	mem = vector<int>(year + 1, -1);
	return  cowCount_three(year);
}

int main()
{
	int year;

	while (cin >> year && year > 0)
		cout << cowCount(year) << endl;

	return 0;
}