《趣学算法》第四章 动态规划代码实现(Java)
2018-01-22 17:24
253 查看
4.3 最长的公共子序列
import java.util.Scanner; public class Test4_3 { static String s1; static String s2; public static void main(String[] args) { Scanner scanner=new Scanner(System.in); System.out.println("输入字符串s1:"); s1=scanner.next(); System.out.println("输入字符串s2:"); s2=scanner.next(); int len1=s1.length(); //计算两个字符串的长度 int len2=s2.length(); int[][] c=new int[len1+1][len2+1]; //存放公共子序列的最大长度 int[][] b=new int[len1+1][len2+1]; //记录来源 for(int i=0;i<=len1;i++) c[i][0]=0; //初始化第一列为0 for(int j=0;j<=len2;j++) c[0][j]=0; //初始化第一行为0 LCSL(c,b); //求解最长公共子序列 System.out.println("s1和s2的最长公共子序列长度是:"+c[len1][len2]); System.out.print("s1和s2的最长公共子序列是:"); print(len1,len2,b); //递归构造最长公共子序列最优解 } /*求解最长公共子序列*/ public static void L 4000 CSL(int[][] c,int[][] b) { int i,j; for(i=1;i<=c.length-1;i++) { //控制s1的序列,即遍历s1的每个字符 for(j=1;j<=c[i].length-1;j++) { //控制s2的序列,即用s1的字符与s2的所有字符进行比较 if(s1.charAt(i-1)==s2.charAt(j-1)) { //字符下标从0开始 //如果当前字符相同,则公共子序列的长度为该字符前的最长公共序列+1 c[i][j]=c[i-1][j-1]+1; b[i][j]=1; } else { if(c[i][j-1]>=c[i-1][j]) { //找出两者最大值,若相等默认取左侧 c[i][j]=c[i][j-1]; //取左侧值 b[i][j]=2; } else { c[i][j]=c[i-1][j]; //取上面值 b[i][j]=3; } } } } } /*递归构造最长公共子序列最优解*/ public static void print(int i,int j,int[][] b) { if(i==0||j==0) return; //递归结束条件 if(b[i][j]==1) { //来源左上角 print(i-1,j-1,b); System.out.print(s1.charAt(i-1)); } else if(b[i][j]==2) print(i,j-1,b); //来源左侧 else print(i-1,j,b); //来源上面 } }
程序运行结果如下:
4.4 编辑距离
import java.util.Scanner; public class Test4_4 { public static void main(String[] args) { Scanner scanner=new Scanner(System.in); System.out.println("输入字符串str1:"); String str1=scanner.next(); System.out.println("输入字符串str2:"); String str2=scanner.next(); int answer=editDistance(str1,str2); //求编辑距离 System.out.println(str1+"和"+str2+"的编辑距离是:"+answer); } public static int editDistance(String str1,String str2) { int len1=str1.length(); //计算字符串的长度 int len2=str2.length(); int[][] d=new int[len1+1][len2+1]; //d[i][j]表示str1前i个字符和str2前j个字符的编辑距离 for(int i=0;i<=len1;i++) //当第二个字符串长度为0时,编辑距离初始化为i d[i][0]=i; for(int j=0;j<=len2;j++) //当第一个字符串长度为0时,编辑距离初始化为j d[0][j]=j; for(int i=1;i<d.length;i++) { //遍历str1的每个字符 for(int j=1;j<d[i].length;j++) { //与第二个字符串的每个字符进行比较 int diff; //判断str1[i]是否等于str2[j],相等为0 if(str1.charAt(i-1)==str2.charAt(j-1)) { //字符串小标从0开始 diff=0; } else diff=1; int temp=Math.min(d[i-1][j]+1, d[i][j-1]+1); //去三者中最小值 d[i][j]=Math.min(temp,d[i-1][j-1]+diff); } } return d[len1][len2]; } }
程序运行结果如下:
4.5 游艇租赁
import java.util.Scanner; public class Test4_5 { static int n; public static void main(String[] args) { Scanner scanner=new Scanner(System.in); System.out.println("请输入站点的个数n:"); n=scanner.nextInt(); System.out.println("请依次输入各站点之间的租金:"); int[][] r=new int[n+1][n+1]; //存放各站点之间的租金 int[][] m=new int[n+1][n+1]; //各个子问题的最优值 int[][] s=new int[n+1][n+1]; //各个子问题的最优决策 for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { r[i][j]=scanner.nextInt(); m[i][j]=r[i][j]; //初始化m数组 } } rent(m,s); //求最少租金 System.out.println("花费最少的租金为:"+m[1] ); System.out.print("最少租金经过的站点:1"); print(1,n,s); System.out.println(); scanner.close(); } /*最少租金求解函数*/ public static void rent(int[][] m,int[][] s) { int i,j,k,d; for(d=3;d<=n;d++) { //将问题划分为小规模d,3个站点、4个站点...n个站点 for(i=1;i<=n-d+1;i++) { //子问题的初始站点 j=i+d-1; //子问题的终点站点 for(k=i+1;k<j;k++) { //可停靠站点 int temp=m[i][k]+m[k][j]; //在站点k停留 if(temp<m[i][j]) { //停留后的租金和比直达的租金便宜 m[i][j]=temp; s[i][j]=k; //记录停靠点 } } } } } /*求得停靠点,当s[i][j]=0时说明中间没有停靠点,输出站点j,否则划分为两个子问题*/ public static void print(int i,int j,int[][] s) { if(s[i][j]==0) { System.out.print("——"+j); return; } print(i,s[i][j],s); print(s[i][j],j,s); } }
程序运行结果如下:
4.6 矩阵连乘
import java.util.Scanner; public class Test4_6 { static int n; public static void main(String[] args) { Scanner scanner=new Scanner(System.in); System.out.println("请输入矩阵的个数n:"); n=scanner.nextInt(); int[] p=new int[n+1]; //记录矩阵行列 int[][] m=new int[n+1][n+1]; //最优值数组 int[][] s=new int[n+1][n+1]; //最优决策数组 System.out.println("请依次输入每个矩阵的行数和最后一个矩阵的列数:"); for(int i=0;i<=n;i++) p[i]=scanner.nextInt(); matrixChain(p,m,s); //矩阵连乘求解函数 print(1,n,s); System.out.println(); System.out.println("最小计算量的值为:"+m[1] ); } /*矩阵连乘求解函数*/ public bd17 static void matrixChain(int[] p,int[][] m,int[][] s) { int i,j,r,k; for(r=2;r<=n;r++) { //2个矩阵连乘、3个矩阵连乘...n个矩阵连乘 for(i=1;i<=n-r+1;i++) { //r个矩阵开始矩阵的下标 j=i+r-1; //结束矩阵 m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j]; //k=i时的乘法次数 s[i][j]=i; //子问题的最优策略是i for(k=i+1;k<j;k++) { //对从i到j的所有策略求最优值 int temp=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j]; if(temp<m[i][j]) { m[i][j]=temp; s[i][j]=k; } } } } } /*最优解输出函数*/ public static void print(int i,int j,int[][] s) { if(i==j) { System.out.print("A"+i); return; } System.out.print("("); print(i,s[i][j],s); print(s[i][j]+1,j,s); System.out.print(")"); } }
程序运行结果如下:
4.9 0-1背包问题
import java.util.Scanner; public class Test4_9 { public static void main(String[] args) { int n,W; //n表示n个物品,W表示购物车容量 Scanner scanner=new Scanner(System.in); System.out.println("请输入物品的个数n:"); n=scanner.nextInt(); System.out.println("请输入购物车的容量W:"); W=scanner.nextInt(); int[] w=new int[n+1]; //存放所有物品的重量 int[] v=new int[n+1]; //存放所有物品的价值 int[][] c=new int[n+1][W+1]; //表示前i个物品放入容量为j的购物车获得的最大价值 System.out.println("请依次输入每个物品的重量w和价值v,用空格分开:"); for(int i=1;i<=n;i++) { w[i]=scanner.nextInt(); v[i]=scanner.nextInt(); } //计算c[i][j] for(int i=1;i<=n;i++) { //控制物品个数 for(int j=1;j<=W;j++) { //控制容量大小 if(w[i]>j) //物品重量大于购物车容量,则不放入第i个物品 c[i][j]=c[i-1][j]; else c[i][j]=Math.max(c[i-1][j],c[i-1][j-w[i]]+v[i]);//比较放入此物品与不放入此物品哪个价值更大 } } System.out.println("装入购物车的最大价值为:"+c [W]); //逆向构造最优解 int[] x=new int[n+1]; //表示第i个物品是否放入购物车 int j=W; for(int i=n;i>0;i--) { //从最后一个物品开始判断 if(c[i][j]>c[i-1][j]) { //说明第i个物品放入购物车 x[i]=1; j-=w[i]; } else x[i]=0; //说明第i个物品没有放入购物车 } System.out.println("装入购物车的物品为:"); for(int i=1;i<=n;i++) { if(x[i]==1) System.out.print(i+" "); } } }
程序运行结果如下:
相关文章推荐
- 《趣学算法》 第七章线性规划网络流代码实现(Java)
- 算法与数据结构-动态规划 讲解与java代码实现
- 动态规划算法(后附常见动态规划例题及Java代码实现)
- 动态规划算法(后附常见动态规划为题及Java代码实现)
- 《趣学算法》第三章 分治法代码实现(Java)
- 利用newxy(新坐标),不写一行java代码实现多项查询
- JAVA 实现内存管理 和 LOG 保存的 代码
- Java中数据库事务处理的实现-JSP教程,Java技巧及代码
- 实现高效的数据库连接池(附带完整代码C#和Java实现)
- java代码中实现字符编码转换(解决中文乱码问题)
- Jsp/Java代码分离.实现页面真正的代码分离 设计原理
- 用java实现论坛ubb的代码
- 购物车的 java 代码实现方法
- Jsp/Java代码分离.实现页面真正的代码分离 测试代码是否按想法运行,下载原代码
- 实现高效的数据库连接池(附带完整代码C#和Java实现)
- ajax,jsp,java技术实现行政区划代码三级关联下拉框
- 用java实现简单的网络通信,相当于一个最简单的控制台qq(附代码) 推荐
- newxy+struts实现零java代码或极少java代码开发以数据为中心的web运用系统 作者:胡立新
- Java实现将Map转换为List的小代码
- 3DES加密java的实现代码