动态规划问题求解

刷leetcode198题时,遇到动态规划的问题,重新预习加复习了一次动态规划的相关知识。

动态规划(Dynamic Programming):

  • 基于一个递推公式及一个或多个初始状态
  • 当前子问题的解由上一次子问题的解推出
  • 找到状态之间的转移方式,即转到状态转移方程。(这一点特别重要)
最常见的例子:LIS(Longest Increasing Subsequence)
   设d(i):表示前i个数中的以A[i]结尾的最长非降子序列的长度
       d(i = max{ 1, d(j)+1 }, 其中j < i,A[J] <= A[i]
找到递推关系式后根据关系式写出代码。

public class  LIS{
	
	public int lis(int [] a){
		int leng = a.length;
		int [] b = new int[leng];
		int len  = 1;
		for(int i = 0; i < leng; i++){
			b[i] = 1;
			for(int j = 0; j < i; j++){
				if( (a[i] > a[j]) && (b[i] < (b[j] + 1)))
					b[i] = b[j] +1;
			}
			if(len < b[i]) len = b[i];
		}
		return len;	
	}
	
	public static void main(String [] args){
	    LIS li = new LIS();
		int [] a = {4,5,1,2,3,7,8,9};
		System.out.print("The longest increasing subsequence length is " + li.lis(a));
	}
}

上述算法的复杂度为O(n^2),可化简至O(nlgn)

public class LIS{
	public int find_position(int [] arr, int s, int e, int key){
		int mid;
		if(arr[e] < key) return e+1;
		while(s < e){
			mid = s +(e-s)/2;
			if(arr[mid] <= key)
				s = mid + 1;
			else e =mid;
		}
		return s;
	}
	public int lis(int [] d){
		int i = 0, len =1;
		int n = d.length;
		int [] end = new int [n];
		end[1] = d[0];
		 
		for(i = 1; i< n; i++){
			int pos = find_position(end, 1, len, d[i]);
			end[pos] = d[i];
			if(pos > len) len = pos;
		}
		return len;
	}
	public static void main(String [] args){
		LIS list1 = new  LIS();
		int [] a = {2,1,5,3,6,4,8,9,7};
    	int	len = list1.lis(a);
		System.out.println("The longest increasing subsequence' s length is  " + len);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值