暴力递归到动态规划
动态规划的适用条件
-
总结
- 从左到右尝试的模型
- 范围上的尝试模型
- 多样本位置全对应的尝试模型
- 寻找业务限制的尝试模型
-
总结
题->找到暴力递归方法(尝试,具有重复解)->可变参数,不讲解组织->记忆化搜索->精细化组织->经典的动态规划
从左往右尝试的模型1
规定1和A对应,2和b对应,3与c对应,那么一个字符串,比如"111"就可以转化为:“AAA”,“KA”,“AK”,给定一个只有数字字符组成的字符串str,返回多少种转化结果。
暴力递归
package Digui;
public class convertLetterString {
//str只包含数字字符
//返回多少种转化方案
public static int num(String str){
if (str==null||str.length()==0) {
return 0;
}
return process(str.toCharArray(), 0);
}
//str[0...i-1]已经转化完了,固定了
//i之前的位置,如何转化已经做好决定了,不用再关心
//i..之后有多少种转化结果
public static int process(char[] str,int i){
if (i==str.length) {
return 1;//两种解释,没有字符的时候能不能转化,能,转化为1
//我找到一种有效的转化,str[0...i-1]已经转化完了,固定了,所以终止位置,我收集一点答案1.
//"11"变为“AA","K"
}
//i没有到终止位置
if (str[i]=='0') {
return 0;
}
//str[i]不是‘0’
if (str[i]=='1') {
int res=process(str, i+1);//i自己作为单独部分,后续有多少转化
if (i+1<str.length) {
res+=process(str, i+2);//i和i+1自己作为单独部分,后续有多少转化
}
return res;
}
if (str[i]=='2') {
int res=process(str, i+1);//i自己作为单独部分,后续有多少转化
//i和i+1自己作为单独部分,并没有
if (i+1<str.length && str[i+1]>='0'&&str[i+1]<='6') {
res+=process(str, i+2);//i和i+1自己作为单独部分,后续有多少转化
}
return res;
}
//str[i]为'3'-'9'
return process(str, i+1);
}
public static void main(String[] args) {
String str="111";
System.out.println(num(str));
}
}
//3.AAA,AK,KA
动态规划
package Digui;
public class convertLetterStringdp {
public static int dpways(String s){
if (s==null||s.length()==0) {
return 0;
}
char[] str=s.toCharArray();
int N=s.length();
int[] dp=new int [N+1];
dp[N]=1;
for(int i=N-1;i>=0;i--){
if (str[i]=='0') {
dp[i]=0;
}
if (str[i]=='1') {
dp[i]=dp[i+1];
if (i+1<str.length) {
dp[i]+=dp[i+2];
}
}
if (str[i]=='2') {
dp[i]=dp[i+1];
if (i+1<str.length && str[i+1]>='0'&&str[i+1]<='6') {
dp[i]+=dp[i+2];
}
}
}
return dp[0];
}
public static void main(String[] args) {
String str="111";
System.out.println(dpways(str));
}
}
从左往右尝试的模型2
给定两个长度都为N的weights和values,weights[i]和values[i]分别代表i号物品的重量和价值,给定一个正数bag,表示一个载重的bag的袋子。给定一个正数bag,表示一个载重bag的袋子。你装的物品不能超过这个重量。返回你能装下最多的价值是多少?
暴力递归版
package Digui;
public class knaspack {
public static int getMaxvalue(int[] w,int [] v,int bag){
return Process(w,v,0,0,bag);
}
//不变,v[],w[],bag
//index..最大价值
//0..index-1做了货物选择,使你已经达到的重量是多少alreadyW
//如果返回-1,则认为没有这个方案。返回不是-1,则返回的值是一个真实的价值
public static int Process(int[] w,int [] v,int index,int alreadyW,int bag ){
if (alreadyW>bag) {
return -1;
}
//重量没超
if (index==w.length) {
return 0;
}
//没有要当前的货,后续的最大价值
int p1=Process(w, v, index+1, alreadyW, bag);
//要了当前的货,后面的货最大的价值
int p2next=Process(w, v, index+1, alreadyW+w[index], bag);
int p2=-1;
if (p2next!=-1) {
p2=v[index]+p2next;
}
return Math.max(p1, p2);
}
public static void main(String[] args) {
int[] weights = {
3, 2, 4