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

dp,洛谷p1044,栈

程序员文章站 2022-07-13 11:51:42
...

dp,洛谷p1044,栈dp,洛谷p1044,栈

思路:
状态: dp(i,j)表示进栈了i个,出栈了j个,显然,i>=j
dp(i-1,j) 再进一个栈 就是dp(i,j) ,dp(i,j-1)再出一个栈就是dp(i,j)
故dp(i,j)=dp(i-1,j)+dp(i,j-1);
边界条件:dp(i,0) 进栈i个,出栈0个,情况只有一种

#include<iostream>
using namespace std;

typedef long long ll;


/*
状态: dp(i,j)表示进栈了i个,出栈了j个,显然,i>=j
dp(i-1,j) 再进一个栈 就是dp(i,j) ,dp(i,j-1)再出一个栈就是dp(i,j)
故dp(i,j)=dp(i-1,j)+dp(i,j-1);
边界条件:dp(i,0) 进栈i个,出栈0个,情况只有一种
*/

ll dp[20][20] = {0};
int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++){
		dp[i][1] = 1;
	}
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= i+1; j++){
			if (i == 1 && j == 1);
			else dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
		}
	}
	cout << dp[n][n];
	return 0;
}


/*
解释一下原理:

建立数组f。f[i]表示i个数的全部可能性。

f[0] = 1, f[1] = 1; //当然只有一个

设 x 为当前出栈序列的最后一个,则x有n种取值

由于x是最后一个出栈的,所以可以将已经出栈的数分成两部分

比x小

比x大

比x小的数有x-1个,所以这些数的全部出栈可能为f[x-1]

比x大的数有n-x个,所以这些数的全部出栈可能为f[n-x]

这两部分互相影响,所以一个x的取值能够得到的所有可能性为f[x-1] * f[n-x]

另外,由于x有n个取值,所以

ans = f[0]*f[n-1] + f[1]*f[n-2] + ... + f[n-1]*f[0];

这,就是传说中的卡特兰数
*/
	int n, f[30];
	int main2()
	{
		//递推实现卡特兰数 
		scanf("%d", &n);
		f[0] = 1, f[1] = 1;
		for (int i = 2; i <= n; i++)
			for (int j = 0; j<i; j++)
				f[i] += f[j] * f[i - j - 1];     //递推公式 
		printf("%d", f[n]);
		return 0;
	}

相关标签: 算法 dp