training 01 recursion and dynamic programming

recursion:


    find a recursion base and try to using recursion function to simplify the problem

POJ 1664 放苹果:

base:

n=1 return 1

recursion function:

case1: one disk without any apples then return f(M,n-1)

case2:every disk has at least one apple  then take one apple from each disk return f(M-n,n) 

so:f(M,n)=f(M-n,n)+f(M,n-1)

#include <iostream>
using namespace std;

int func(int m, int n)//m apple
{
	if (n == 1) return 1;
	if (m < n) return func(m, n - 1);
	return func(m, n - 1) + func(m - n, n);
}

int main()
{
	int num;
	cin >> num;
	int m, n;
	for (int i = 0; i < num; i++) cin >> m, cin >> n, cout << func(m, n) << endl;
}

POJ 1663 The Triangle:

let m be the row number n the colomn number

base:

 a[1][1]=7

recursion function:

if(n=1) return a[m][n]+func(m-1,1)

if(m=n) return a[m][n]+func(m-1,n-1)

so:find the max a[5][n]

#include <iostream>
using namespace std;
int a[100][100];
int func(int m, int n)//m lines
{
	if (m == 1) return a[1][1];
	if (n == 1) return a[m][n] + func(m - 1, 1);
	if (m == n) return a[m][n] + func(m - 1, n - 1);
	else return max(func(m-1,n-1), func(m-1,n))+ a[m][n];
}

int main()
{
	int cols;
	int num;
	cin >> cols;
	int max = 0;
	for (int i = 1; i <= cols; i++)
		for (int j = 1; j <= i; j++)
		{
			cin >> num;
			a[i][j] = num;
		}
	for (int i = 1; i <= cols; i++) { if (func(cols, i) > max) max = func(cols, i); }
	cout << max;
}

Time limit!


Dynamic programming:

dynamic programming=precursion+memorization

It reminds me of the fibonacci problem f(n)=f(n-1)+f(n-2) ,which is extremely time-consuming.

Instead if we store the results in an array.

Dynamic fibonacci:

#include <iostream>
using namespace std;
long dyn[1000];
long fib(long m)
{
	if (m <= 2) return dyn[m] = 1;
	if (dyn[m] != -1) return dyn[m];
	return dyn[m] = fib(m - 2) + fib(m - 1);
}

int main()
{
	for (long i = 0; i < 100; i++)
		dyn[i] = -1;
	for (long i = 3; i < 40; i++)
		cout << fib(i) << endl;
}

POJ 1579 Function Run Fun 

#include <iostream>
#include <ctime>
using namespace std;
long dyn[21][21][21];

int w(int a, int b, int c)
{
	if (a <= 0 || b <= 0||c <= 0) return 1;
	if (a > 20 || b > 20 || c > 20) return w(20, 20, 20);
	if (dyn[a][b][c] != -1) return dyn[a][b][c];
	if (a < b && b < c) return dyn[a][b][c] = w(a, b, c - 1) + w(a, b - 1, c - 1) - w(a, b - 1, c);
	else return dyn[a][b][c] = w(a - 1, b, c) + w(a - 1, b - 1, c) + w(a - 1, b, c - 1) - w(a - 1, b - 1, c - 1);
}

int main()
{
	int a, b, c;
	for (int i = 1; i < 21; i++)
		for (int j = 1; j < 21; j++)
			for (int p = 1; p < 21; p++)
				dyn[i][j][p] = -1;
	while(cin>>a>>b>>c,a!=-1||b!=-1||c!=-1)
		cout << "w(" << a << ", " << b << ", " << c << ") = " << w(a, b, c) << endl;
}

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值