动态规划算法学习十例之二

例一:计算二项式系数:

在排列组合里面,我们有下面的式子(很容易用组合的定义来证明):

[img]http://dl.iteye.com/upload/attachment/0074/5221/2f21cf96-e6c5-3676-a114-3698fce0aec9.jpg[/img]

这个式子将C(n , k)的计算问题表述为了(问题描述)C(n-1 , k -1)和C(n -1, k)两个较小的重叠子问题。
/* 
* 用动态规划算法计算C(n,k)
* 输入:一对非负整数n>=k>=0
* 输出:C(n,k)的值
*/
import java.util.*;

public class Binomial {
int C[][];
int Computing(int n,int k){
C = new int[n+1][n+1];
for(int i=0;i<=n;i++){
for(int j=0;j<=Math.min(i, k);j++){
if(j==0||j==i){
C[i][j] = 1;
}
else{
C[i][j] = C[i-1][j-1]+C[i-1][j];
}
}
}
return C[n][k];
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入n:");
int n = in.nextInt();
System.out.println("请输入k(0<=k<=n):");
int k = in.nextInt();
Binomial b=new Binomial();
System.out.println("C["+n+","+k+"] = "+b.Computing(n, k));

for(int i = 0;i <= 8;i++)
System.out.println("C" + "[" + 8 + "," + i + "]" + " ———— " +b.Computing(8,i));

}
}




运行:
C:\java>java Binomial
请输入n:
5
请输入k(0<=k<=n):
5
C[5,5] = 1
C[8,0] ———— 1
C[8,1] ———— 8
C[8,2] ———— 28
C[8,3] ———— 56
C[8,4] ———— 70
C[8,5] ———— 56
C[8,6] ———— 28
C[8,7] ———— 8
C[8,8] ———— 1

例二:斐波那契数列(动规实现)
无穷数列1,1,2,3,5,8,13,21,34,55,…,被称为Fibonacci数列。它可以递归地定义为:
[img]http://dl.iteye.com/upload/attachment/0074/5223/c61e2022-4aa8-3622-80e7-fa4d5287b8e8.jpg[/img]

2 程序实现

缓存是为了减少重复计算。

import java.util.HashMap;

import java.util.Map;



public class FibonacciUtil {

static Map<Integer, Integer> cache = new HashMap<Integer, Integer>();



public static int fib(int n) {

if (n == 0 || n == 1)

return 1;

if (null != cache.get(n))

return cache.get(n);



int ret = fib(n - 1) + fib(n - 2);

cache.put(n, ret);

return ret;

}



public static void listFib(int n){

for(int i=1;i<n;i++){

System.out.print(fib(i)+",");

}

}



public static void main(String[] args) {

listFib(10);

}

}


若求问题的唯一解(最优解),先分解成为子问题,而子问题的解也是唯一的(最优的)。子问题有重叠,为了减少重复计算,缓存重叠部分计算结果;
这两点也正是动规算法的精髓。实际上,这个例子是动规算法最简单的一个实例。

下载源代码。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值