动态规划——在做题中理解你的美
来源:互联网 发布:知乎补充回答 编辑:程序博客网 时间:2024/05/17 05:11
一、求数组最大子数组和
子数组必须是连续的,数组中可能包含有:正整数,零,负整数三种中的一种或多种。
方法一:可以用普通的方法枚举所有的连续子数组,然后求出最大的子数组和,时间复杂度为O(n*n)。
方法二:动态规划!
方法一代码:
int MaxSubString(int[] A, int n){ int max = min; //初始值为负无穷大 int sum; for(int i = 0; i < n; i++) { sum = 0; for(int j = i; j < n; j++) { sum += A[j]; if(sum > max) max = sum; } } return max;}
方法二代码:
import java.util.Scanner;public class BigSubArraySum { public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.println("请输入n个整数"); int n = input.nextInt(); int[] arr = new int[n]; for (int i = 0; i < n; i++) { arr[i] = input.nextInt(); } int max = arr[0]; int currentMax = arr[0]; for (int i = 1; i < arr.length; i++) { //currentMax = (currentMax >= 0) ? arr[i] + currentMax : arr[i]; currentMax = Math.max(arr[i] + currentMax,arr[i]); max = Math.max(max, currentMax); } System.out.println(max); }}
数组: {0, -2, 3, 5, -1, 2} 返回值为 9,因为连续子数组3+5-1+2=9>3+5=8;
二、硬币问题
(还是有问题,当货币中为2,3,4或者其他就会出现bug,待解决)
public class MinCoins { public static void main(String[] args) { int[] coins = {1,3,5}; //coins数组存放各个无重复面值 int value = 17; //value表示需要凑成的钱数 int[] jilu = new int[value]; //记录每一步的面值 int min = new MinCoins().solution(coins, value, jilu); for (int i = value - 1; i >= 0;) { System.out.print(jilu[i] + "->"); i = i - jilu[i];//倒序输出每一步用的哪种币 } System.out.println(); System.out.println(min); } private int solution(int[] coins, int value, int[] jilu) { int[] mins = new int[value + 1]; //数组mins表示凑成多少钱所需最小钱币数目,为了使索引能达到value,加1 mins[0] = 0; //凑成0元所需0个 for (int i = 1; i <= value; i++) //将数组中的数初始化为最大值 mins[i] = Integer.MAX_VALUE; for (int i = 1; i <= value; i++) { //从凑1元钱开始,递增直至value for (int j = 0; j < coins.length; j++) {//j表示第(j+1)种币 if (coins[j] <= i) { //意思是比较所有种类的币是不是比所要凑的值小, //如若比要凑得值还大就跳过比下一种币 mins[i] = Math.min(mins[i] , mins[i - coins[j]] + 1); //将满足coins[j] <= i的coins[j]遍历一遍,则mins[i]存储的值就是几种情况中的最小值 jilu[i - 1] = coins[j];//记录每步所使用的币值 } } } return mins[value]; }}
三、背包问题
w[i] : 第i个物体的重量;
p[i] : 第i个物体的价值;
arr[i][m] : 前i个物体放入容量为m的背包的最大价值;
arr[i-1][m] : 前i-1个物体放入容量为m的背包的最大价值;
arr[i-1][m-w[i]] : 前i-1个物体放入容量为m-w[i]的背包的最大价值;
由此可得:
arr[i][m]=max{arr[i-1][m-w[i]]+p[i] , arr[i-1][m]}
public class BackPack { public static void main(String[] args) { int[] w = { 3, 4, 5 };//每个货物的重量 int[] p = { 4, 5, 6 };//每个货物的价值(与上面对应) int m=10; //背包最大承重 int n=w.length; int[][] arr=new int[n+1][m+1];//定义二维数组存储每种情况下背包里的物品价值 int i,j; for(i=0;i<=n;i++){ //将前(i+1)个物品放入承重为0的包里价值为0 arr[i][0]=0; } for(j=0;j<=m;j++){ //将前0个物品放入承重为j的包里价值为0 arr[0][j]=0; } for(j=0;j<=m;j++){ //j表示背包承重(从0递增至m) for(i=1;i<=n;i++){ //i表示第i个货物 if(j<w[i-1]){ //如果第i个货物的重量w[i-1]大于背包承重则舍弃这个货物 arr[i][j]=arr[i-1][j]; }else{ //如果第i个货物的重量w[i-1]小于背包承重则取两者之间最大值 arr[i][j]=Math.max(arr[i-1][j-w[i-1]]+p[i-1],arr[i-1][j]); }//或许你会问为什么取最大,加入第i个肯定比不加大呀!你说的没错但是你必须考虑能不能加,至于能不能加交给它前面的去考虑,这也是动态规划的思想之一 } } System.out.println(arr[n][m]); }}
四、最长公共子序列
public class LCS { public static void main(String[] args) { String str1="ABCDABDC"; String str2="BBCDCADBCAD"; char[] ch1=str1.toCharArray(); char[] ch2=str2.toCharArray(); int m=ch1.length; int n=ch2.length; int[][] arr=new int[m+1][n+1]; int i,j; for(i=0;i<=m;i++){ arr[i][0]=0; } for(j=0;j<=n;j++){ arr[0][j]=0; } for(i=1;i<=m;i++){ for(j=1;j<=n;j++){ if(ch1[i-1]==ch2[j-1]){ arr[i][j]=arr[i-1][j-1]+1; }else{ arr[i][j]=Math.max(arr[i-1][j], arr[i][j-1]); } } } System.out.println(arr[m][n]); }}
0 0
- 动态规划——在做题中理解你的美
- 动态规划的理解
- 《编程之美》买书问题——动态规划
- 对动态规划原理理解的例子,先看看这个在看看动态规划剖析
- 【美团】动态规划(有点难理解)
- 动态规划的一点理解
- 动态规划算法的理解
- 关于动态规划的理解
- 动态规划的个人理解
- 对于动态规划的理解
- 简单的动态规划问题(帮助理解动态规划)
- 算法之美:动态规划
- 【美团】 动态规划问题
- 动态规划之:让你轻松理解背包算法
- 动态规划-美团笔试-字符串计数-恶心的dp
- 动态规划系列(1)——金矿模型的理解
- 动态规划三部曲之一个故事教你透彻理解动态规划(一)
- 动态规划三部曲之一个故事教你透彻理解动态规划(一)
- POJ 1845 约数和+二分等比和+逆元
- 客户端http请求 会带ip吗
- 将QQ截图添加至右键菜单
- 51nod-1240莫比乌斯函数
- 为你详细解读HTTP请求头的具体含意
- 动态规划——在做题中理解你的美
- 解决会话多个请求之间数据共享的问题:使用Cookie
- javaScript基础(二)
- C++ 运算符理论小结
- 深入实践boost读书笔记1
- 定位器
- HTTP 头部解释
- 计算机的组成及其功能
- 视频解码和硬解码