动态规划----线性动态规划
2017-04-03 14:59
309 查看
一、朴素最长非降子序列
1.问题引入
现输入一行数字,要求输出其中最长的非降子序列。如输入 5 3 4 8 6 7,应输出4;
再如输入3 4 8 6 7,应输出4。
2.思路分析
设dp[i]表示遍历到第i个数时最长子序列的值,首先从第一个数开始,dp[0]=1,这是已知值。之后从i=1开始,逐一与前面的数比较,可设j<i,则如果第i个数大于等于第j个数,dp[i]=dp[j]+1,否则dp[i]=dp[i-1]。对于所有的j,取dp[i]的最大值即可。由此得到状态转移方程dp [i]=max{dp[j]+1}。
3.代码如下:
package 动态规划__线性动态规划; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class 朴素最长非降子序列 { public static void main(String args[]) throws IOException{ BufferedReader buf=new BufferedReader(new InputStreamReader(System.in)); String str=buf.readLine(); String s[]=str.split(" "); int dp[]=new int[s.length]; dp[0]=1; for(int i=1;i<s.length;i++){ for(int j=0;j<i;j++){ if(Integer.parseInt(s[i])>=Integer.parseInt(s[j])) dp[i]=Math.max(dp[j]+1, dp[i]); else dp[i]=dp[i-1]; } } System.out.print(dp[s.length-1]); } }
二、方块消除游戏
三、最长公共序列数问题
1.问题引入:
给定两个字符串A和B,返回两个字符串的最长公共子序列的长度。例如,A="1A2C3D4B56”,B="B1D23CA45B6A”,”123456"或者"12C4B6"都是最长公共子序列。给定两个字符串A和B,同时给定两个串的长度n和m,请返回最长公共子序列的长度。保证两串长度均小于等于300。测试样例:第一行输入一个字符串,第二行再输入一个字符串。最后输出最长公共子串的长度。如:1A2C3D4B56B1D23CA45B6A
输出:6
2.思路分析:
设dp[m] ,为A的前n个字符与B的前m个字符的公共序列长度,则当A
==B[m]的时候,dp[i][j] =
max(dp[i-1][j-1]+1,dp[i-1][j],dp[i][j-1]),否则,dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);
3.代码如下:
package 动态规划__线性动态规划; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class 最长公共子串 { public static void main(String args[]) throws IOException{ BufferedReader buf=new BufferedReader(new InputStreamReader(System.in)); String s1=buf.readLine(); String s2=buf.readLine(); String s11[]=s1.split(""); String s21[]=s2.split(""); int dp[][]=new int[s11.length+1][s21.length+1]; for(int i=0;i<s11.length;i++) dp[i][0]=0; for(int j=0;j<s21.length;j++) dp[0][j]=0; for(int i=1;i<=s11.length;i++){ for(int j=1;j<=s21.length;j++){ if(s11[i-1].equals(s21[j-1])) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=Math.max(dp[i-1][j], dp[i][j-1]); } } System.out.println(dp[s11.length][s21.length]); } }
现在如果是要把这个最长公共子序列输出来,可以这样:
public class MaxString { public static void main(String[] args) { String a=max("qwerabcdtyuiop","xcabcdvbn"); System.out.println(a); } public static String max(String s1,String s2){ String dp[][]=new String[s1.length()+1][s2.length()+1]; for(int i=0;i<=s1.length();i++){ for(int j=0;j<=s2.length();j++){ dp[i][j]=""; } } for(int i=0;i<s2.length();i++) dp[0][i]=""; for(int j=0;j<s1.length();j++) dp[j][0]=""; for(int i=1;i<=s1.length();i++){ for(int j=1;j<=s2.length();j++){ if(s1.charAt(i-1)==s2.charAt(j-1)){ dcd4 dp[i][j]=dp[i-1][j-1]+s1.charAt(i-1); }else{ if(dp[i-1][j].length()>dp[i][j-1].length()) dp[i][j]=dp[i-1][j]; else dp[i][j]=dp[i][j-1]; } } } return dp[s1.length()][s2.length()]; } }
再看一个相似的例子:构造回文数问题,现输入一个字符串,则至少删除几个元素可以使这个字符串成为一个回文字符串,输出这个最小值。这题也可以转化为最长公共子序列问题,我们把原字符串逆序得到一个新的字符串,求出这两个字符串的最长公共子序列长度,再用原字符串的长度减去这个最长公共子序列的长度即为所求值。
代码如下:
package 动态规划; import java.util.Scanner; public class 构造回文字符串 { public static void main(String args[]){ String str=new Scanner(System.in).nextLine(); int max=Hui(str,str.length()); System.out.println(max); } public static int Hui(String str,int len){ String rev=new StringBuffer(str).reverse().toString(); int dp[][]=new int[len+1][len+1]; for(int i=0;i<len+1;i++ ) dp[i][0]=dp[0][1]=0; for(int i=1;i<=len;i++){ for(int j=1;j<=len;j++){ if(str.charAt(i-1)==rev.charAt(j-1)) dp[i][j]=dp[i-1][j-1]//把当前比较的两个字符去掉,前面匹配的有多少个 +1; else dp[i][j]=Math.max(dp[i-1][j], dp[i][j-1]); } } int max=dp[len][len];//最大匹配数 return len-max; } }
相关文章推荐
- 机器分配-分组背包&&线性动态规划
- SDAU 编程练习三 动态规划和动态规划与背包问题相结合的问题
- 打砖块【动态规划】(我的动态规划到底是有多 烂!)
- 【LeetCode】Jump Game (一维动态规划 + 线性扫描)
- 【LeetCode】Jump Game (一维动态规划 + 线性扫描)
- 动态规划第五讲——leetcode上的题目动态规划汇总(上)
- 着手SDUT OJ提高实验—动态规划,之前对动态规划的复习#Round1
- 动态规划(2):动态规划的三种形式
- 动态规划之01背包问题 通俗理解动态规划的过程
- 什么是动态规划?动态规划的意义是什么?
- 转【算法之动态规划(四)】动态规划笔试例题详解
- 动态规划第六讲——leetcode上的动态规划汇总(下)
- 什么是动态规划?动态规划的意义是什么?
- 普及练习场 线性动态规划 导弹拦截
- 动态规划——线性
- 线性规划、动态规划等几个概念
- 通过金矿模型介绍动态规划 (很好的动态规划入门介绍)
- 动态规划 -- 动态规划基础
- 动态规划入门 & 线性动态规划
- 【算法之动态规划(一)】动态规划(DP)详解