动态规划算法

时间:2020-09-03 17:06:29   收藏:0   阅读:51

求数组中不相邻的最大值

解决方案,假设opt数组为最优解,比如opt[6]就表示arr数组中下标0到6这段的最优解

即opt[n]=Math.max(opt[n-1],opt[n-2]+arr[n])

上诉公式表示 不取下标为n的选项和取下标为n的选项两种方案的最大值

边界为 opt[0]=arr.get(0) opt[1]=Math.max(arr.get(0),arr.get(1)),还是比较好理解的。

/**
	 * 获取数组arr中不相邻的数字相加最大值
	 * @param arr
	 * @return
	 */
	private static Integer getMaxValue(List<Integer> arr){
		Integer[] opt=new Integer[arr.size()];
		opt[0] = arr.get(0);
		opt[1] = Math.max(arr.get(0), arr.get(1));
		for(int i=2;i<arr.size();i++){
			Integer a = arr.get(i) + opt[i - 2];
			Integer b = opt[i - 1];
			opt[i] = Math.max(a, b);
		}
		System.out.println(JSON.toJSONString(opt));
		return opt[arr.size() - 1];
	}

求数组中是否存在不相邻的选项和为某值

递归方案:

/**
	 * 递归方式求list数组中,是否存在不相邻的数字和为result
	 * @param list
	 * @param result
	 * @return
	 */
	private static boolean containSubset(List<Integer> list,Integer length,Integer result){
	    if(result==0)return true;
		if(length.equals(1)){
			return list.get(0).equals(result);
		}else if(length.equals(2)){
			return list.get(0).equals(result) || list.get(1).equals(result);
		}

		if(list.get(length-1)>result){
			//不选
			return containSubset(list, length - 1, result);
		}
		boolean A = containSubset(list, length - 2, result - list.get(length - 1));
		boolean B = containSubset(list, length - 1, result);
		return A || B;
	}

动态规划方案:

	/**
	 * 动态规划 求list数组中不相邻的数字和是否可以为result()
	 * @param list
	 * @param result
	 * @return
	 */
	private static boolean dp_subset(List<Integer> list,Integer result){
		Boolean[][] arr = new Boolean[list.size()][result + 1];
        for(int i=0;i<list.size();i++){
			arr[i][0] = true;
		}
        for(int j=1;j<=result;j++){
			arr[0][j] = list.get(0).equals(j);
		}
        for(int j=1;j<=result;j++){
			arr[1][j] = arr[0][j] || list.get(1).equals(j);
		}

        for(int i=2;i<list.size();i++){
        	for(int j=1;j<result+1;j++){
               if(list.get(i)>j){
				   arr[i][j] = arr[i - 1][j];
			   }else{
				   boolean A = arr[i - 1][j];
				   boolean B = arr[i - 2][j - list.get(i)];
				   arr[i][j] = A || B;
			   }
			}
		}
		showArr(arr);
		return arr[list.size() - 1][result];
	}

动态规划方案不太好理解,这里举例

list为5, 4, 3, 1, 6, 2, 7,result为12

       0     1     2     3     4     5     6     7     8     9     10    11   12
5    true false false false false  true false false false false false false false 
4    true false false false  true  true false false false false false false false 
3    true false false  true  true  true false false  true false false false false 
1    true  true false  true  true  true  true false  true false false false false 
6    true  true false  true  true  true  true false  true  true  true  true false 
2    true  true  true  true  true  true  true  true  true  true  true  true false 
7    true  true  true  true  true  true  true  true  true  true  true  true  true 

纵坐标为list数组中的具体值,横坐标为result

每个坐标的意思就是在子数组中是否存在不相邻的和为坐标值的组合

比如arr[2,4]表示5,4,3三个子集中是否存在不相邻的组合和为4

可以明星看出最右下角的二维数组值就是要的结果。

最长回文子串

	/**
	 * 动态规划方式
	 * @param s
	 * @return
	 */
	private static String myTestCode(String s){
		int len = s.length();
		if(len<2)return s;
		char[] arr = s.toCharArray();
		int maxLen=1;
		int begin=0;
		boolean[][] dp = new boolean[len][len];
		for(int j=1;j<len;j++){
			for(int i=0;i<j;i++){
				if(arr[i]!=arr[j]){
					dp[i][j]=false;
				}else{
					if(j-i>2){
						dp[i][j] = dp[i + 1][j - 1];
					}else{
						dp[i][j]=true;
					}
				}
				if(dp[i][j]&&(j-i+1)>maxLen){
					begin=i;
					maxLen = j - i + 1;
				}
			}
		}
		return s.substring(begin, begin + maxLen);
	}

参考

漫画:什么是动态规划?

经典动态规划:0-1 背包问题

看动画轻松理解「递归」与「动态规划」

动态规划解题套路框架

算法-动态规划 Dynamic Programming--从菜鸟到老鸟

浅谈我对动态规划的一点理解---大家准备好小板凳,我要开始吹牛皮了~~~

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!