先看一个高中概率题:小明在一个M*N的街道上从(0,0)走到(m,n)有几种走法(小明不傻,不绕路)?
数学解法:从(0,0)走到(m,n)一共要走过m+n个街道,其中m个横着的,n个竖着的。转化为m个横和n个竖的排列有多少?这个显然就是C(n,m+n).
动态规划解法:
f(m,n)=f(m-1,n)+f(m,n-1);//m,n>0
f(m,n)=f(m-1,n);//m>0,n=0
f(m,n)=f(m,n-1);//m=0,n>0
f(m,n)=1;//m=n=0;
所以用动态规划能求解出C(n,n+m),自然就能求解出C(n,m),m>=n>0;
贴代码:
public class demo {
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 10;
int m = 11;//m>n
demo d = new demo();
System.out.println(d.Cnm(m-n,n));
}
public int Cnm(int n,int m){//求取C(n,m+n);C(n,m)=Cnm(m-n,n)
int[][] temp = new int[n+1][m+1];
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
if(i-1>=0&&j-1>=0)
temp[i][j]=temp[i-1][j]+temp[i][j-1];
else if(i-1>=0)
temp[i][j]=temp[i-1][j];
else if(j-1>=0)
temp[i][j]=temp[i][j-1];
else
temp[i][j]=1;
}
}
return temp[n][m];
}
}