钢条问题
public class 钢条问题 {
public static void main(String[] args) {
int[] p = { 0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30 };
int n = 5;// 钢条长度
int rn = max(n, p);
// int[] baks=new int[p.length];
//
// //初始化备忘录
// for(int i=0;i<baks.length;i++) {
// baks[i]=-1;
// }
// int rn=max(n,p,baks);
System.out.println(rn);
}
// /**
// * 递归求最优解
// * @param p
// * @param p
// * @return
// */
// private static int max(int n, int[] p) {
// if (n == 0)
// return 0;
// int maxPrice = 0;
// for (int i = 1; i <= n; i++) {
// int tempMax = p[i] + max(n - i, p);
// if (tempMax > maxPrice) {
// maxPrice = tempMax;
// }
// }
// return maxPrice;
// }
// /**
// * 动态规划求最优解(备忘录法)
// * @param n
// * @param p
// * @param baks
// * @return
// */
// private static int max(int n, int[] p, int[] baks) {
// if (n == 0)return 0;
// if(baks[n]!=-1) {
// return baks[n];
// }
//
// int maxPrice = 0;
// for (int i = 1; i <= n; i++) {
// int tempMax = p[i] + max(n - i,p, baks);
// if (tempMax > maxPrice) {
// maxPrice = tempMax;
// }
// }
// baks[n]=maxPrice;
// return maxPrice;
// }
/**
* 自底向上求最优解
* @param n
* @param p
* @return
*/
private static int max(int n, int[] p) {
int[] r=new int[n+1];//存储最优解的数组
//数组最小值为0,故这里不用初始化。
for(int i=1;i<=n;i++) {
int maxPrice=0;
for(int j=1;j<=i;j++) {
int temp=p[j]+r[i-j];
if(temp>maxPrice) {
maxPrice=temp;
}
}
r[i]=maxPrice;
}
return r[n];
}
}
小Q拼凑硬币
//低效 import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
public class 小Q拼凑硬币 {
//低效 private static ArrayList<Long> mem = new ArrayList<Long>(Arrays.asList(1L,1L));
//HashMap是存储和查找效率最高的数据结构,但是占用内存较大
//备忘录,存储每种面值n的拼凑方案数
private static HashMap<Long,Long> mem = new HashMap<Long,Long>();
static {
mem.put(-1L,0L);
mem.put(0L,1L);
mem.put(1L,1L);
}
private static long n=0;//面值
/**
* 以2为底n的对数
*/
private static long log2(long n) {
return (long) (Math.log(n) / Math.log(2));
}
/**
* 获得面值n的拼凑方案数
* @param args
* @return
*/
private static long getNum(long n) {
//低效 if(n<0) return 0;//面值为负代表剩余硬币的面值不够拼凑新的组合,方案数返回0。
//低效 if(n<mem.size())return mem.get((int)n);
if(mem.containsKey(n))return mem.get(n);
else {
long k=log2(n);//求出题意中2的指数k
long result=getNum(n-(long )Math.pow(2, k))+getNum((long)Math.pow(2, k+1)-2-n);
mem.put(n,result);//记忆已经求过的值(将每一次求过的值存到索引里头,即要递归)
return result;
}
}
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
n=s.nextLong();
long start=System.currentTimeMillis();
System.out.println(getNum(n));
System.out.println("用时为:["+(System.currentTimeMillis()-start)+"]");
}
}
最大收益
import java.util.ArrayList;
import java.util.Collections;
public class 最大收益 {
/**
* 最大收益
*
* @param index
* @param income
* @param prev
* @return
*/
// private static int maxIncome(int index, int[] income, int[] prev) {
// if (index == 0) {
// return income[0];
// }
// if (prev[index] == -1) {
// return Math.max(income[index], maxIncome(index - 1, income, prev));
// } else {
// return Math.max(income[index] + maxIncome(prev[index], income, prev),
// maxIncome(index - 1, income, prev));
// }
// }
//
// public static void main(String[] args) {//递归
// int[] income = { 5, 1, 8, 4, 6, 3, 2, 4 };// 任务收益
// int[] prev = { -1, -1, -1, 0, -1, 1, 2, 4 };
// // 保存第索引位的任务之前能做的任务的索引
//
// System.out.println(maxIncome(7, income, prev));
// }
// }
/**
* 自底向上实现最大收益
*/
private static int maxIncome(int[] income, int[] prev) {
ArrayList<Integer> result = new ArrayList<Integer>();
result.add(income[0]);
for (int i = 1; i < income.length; i++) {
if (prev[i] == -1) {
result.add(Math.max(income[i] + 0, result.get(i - 1)));
} else {
result.add(Math.max(income[i] + result.get(prev[i]), result.get(i - 1)));
}
}
return Collections.max(result);
}
public static void main(String[] args) {// 递归
int[] income = { 5, 1, 8, 4, 6, 3, 2, 4 };// 任务收益
int[] prev = { -1, -1, -1, 0, -1, 1, 2, 4 };
// 保存第索引位的任务之前能做的任务的索引
// System.out.println(maxIncome(7, income, prev));
System.out.println(maxIncome(income, prev));
}
}