1.定义
2.性质
(1)
(2)
(3)
(4)
3.应用
(1)长度为2n的dyck word的个数。dyck word是一个有n个X和n个Y组成的字串,且所有的前缀字串皆满足X的个数大于等于Y的个数。
假设存在一个最小的k,使得前(2k+1)位中有k个X,(k+1)个Y。因为k是最小的,所以第(2k+1)位是Y。我们将前(2k+1)项中的X变为Y,Y变为X,那么就得到一个有(n+1)个X和(n-1)个Y的序列了,反之亦然。此即为性质(1)。
(2)在n个+1和n个-1组成的序列中,前k项和满足a1+a2+...+ak>=0,1<=k<=2n的序列个数。
假设存在一个最小的k,使得a1+a2+...+ak<0。因为k是最小的,所以a1+a2+...+ak-1=0,ak=-1,并且k是一个奇数。我们将前k项中的+1变为-1,-1变为+1,那么就得到一个有(n+1)个+1和(n-1)个-1的序列了,反之亦然。此即为性质(1)。
(3)包含n组括号的合法运算式的个数。
X表示左括号,Y表示右括号。
(4)n个节点组成不同构二叉树的方案数。
考虑根节点,左子树有i个节点,右子树有(n-1-i)个节点。
(5)(2n+1)个节点组成不同构满二叉树(没有度为1的节点)的方案数 or 拥有(n+1)个叶子节点的满二叉树的数量。
将n个节点组成的二叉树中度为0/1的节点添加2/1个孩子(叶子节点),形成一颗满二叉树。
(6)在n*n格点中不越过对角线的单调路径的个数。
X表示向右,Y表示向上。
(7)凸(n+2)边形三角划分个数。
考虑一条边及以它为底的三角形,假设该三角形左边是i边形,那么右边是(n+1-i)边形。
(8)数字1,2,...,2n被放置在一个2*n的矩形中并保证每行每列的数字升序排列的方案数。
解法一:X表示放在第一行,Y表示放在第二行。
解法二:杨氏矩阵
勾长公式:
(9)用n个长方形填充一个高度为n的阶梯状图形的方法个数。
考虑一个长方形填充第1到(i+1)列,它的右边是一个高度为i的阶梯状图形,下面是一个高度为(n-1-i)的阶梯状图形。
(10)出栈次序。
X表示入栈,Y表示出栈。
(11)将圆上的2n个点成对连接起来所得到的n条线段不相交的方法数。
考虑一条线段,它的左边是圆上的2i个点,右边是圆上的2(n-1-i)个点。
(12)(n+1)个数相乘,所有的括号方案数。
考虑左右两段乘积,左边为i个数的乘积,右边为(n-i)个数的乘积。
4.扩展
(1)n+m个人排队买票,并且满足n>=m,票价为50元,其中n个人手持一张50元钞票,m个人手持一张100元钞票,除此之外大家身上没有任何其他的钱币,并且初始时候售票窗口没有钱,问有多少种排队数能够让大家都买到票。
假设存在一个最小的k,使得前(2k+1)位中有k个50,(k+1)个100。因为k是最小的,所以第(2k+1)位是100。我们将前(2k+1)项中的50变为100,100变为50,那么就得到一个有(n+1)个50和(m-1)个100的序列了,反之亦然。
5.题目
(1)HDU4165
解法一:动态规划
#include<iostream>
using namespace std;
const int n=10;
int g(int f[][n+1],int i,int j)
{
if(j>=0)return f[i][j];
else return 0;
}
int pills(int f[][n+1])
{
int i,j;
for(j=0;j<=n;j++)f[0][j]=1;
for(i=1;i<=n;i++)
{
for(j=0;j<=n-i;j++)f[i][j]=g(f,i-1,j+1)+g(f,i,j-1);
}
return f[n][0];
}
int main()
{
int f[n+1][n+1];
cout<<pills(f)<<endl;
return 0;
}
解法二:
X代表整片,Y代表半片。
(2)阿里巴巴笔试题:16个人按顺序去买烧饼,其中8个人每人身上只有一张5块钱,另外8个人每人身上只有一张10块钱。烧饼5块一个,开始时烧饼店老板身上没有钱。16个顾客互相不通气,每人只买一个。问这16个人共有多少种排列方法能避免找不开钱的情况出现。
C8=1430,总数=1430*8!*8!。
(3)腾讯笔试题:在图书馆一共6个人在排队,3个还《面试宝典》一书,3个在借《面试宝典》一书,图书馆此时没有了面试宝典了,求他们排队的总数。
C3=5,总数=5*3!*3!。