我最近才开始学习动态规划,在网上看到一个简单的例子,也是入门级的,大神路过请无视!
这里是我看的文章链接(传送门):http://www.360doc.com/content/13/0601/00/8076359_289597587.shtml
在这,我把入门例子的“如何用最少枚硬币凑够成11元”和求“最长非降子序列的长度”做一遍
“如何用最少枚硬币凑够成11元”:
import java.util.Scanner;
public class MianZhi {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();// 输入需要找零的钱
sc.close();
int[] mz = new int[] { 1, 3, 5 };// 拥有的硬币面值
int[] dp = new int[n + 1];// 一个保存从1元到n元,各自最少需要多少个硬币数目的数组
// 初始化,假设i元都需要2147483647个硬币
for (int i = 1; i < dp.length; i++)
dp[i] = Integer.MAX_VALUE;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < mz.length; j++) {
// 条件1: i >= mz[j]:表示的是,有比i元要小或相等的面值的硬币
/* 条件2:
* dp[i] > dp[i - mz[j]] + 1:表示的是:
* 首先,dp[i]:是i元当前是由dp[i]个硬币组成
* 然后,dp[i - mz[j]]:表示的是i - mz[j]元需要dp[i - mz[j]]个硬币
* 最后,+ 1是因为条件1满足了,说明可以加上一个面值为mz[j]的硬币
* 两个条件都满足的话,那么dp[i - mz[j]] + 1个硬币可以表示i元
*/
if (i >= mz[j] && dp[i] > dp[i - mz[j]] + 1)
dp[i] = dp[i - mz[j]] + 1;
}
}
//输出i元各自最少需要多少个硬币
for (int i = 1; i < dp.length; i++)
System.out.print(dp[i] + " ");
}
}
import java.util.Scanner;
public class LIS {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 将输入的数字串转成一个字符串数组
String data[] = sc.nextLine().split(" ");
sc.close();
// 将data数组转成int类型的数组
int[] d = new int[data.length];
for (int i = 0; i < d.length; i++)
d[i] = Integer.parseInt(data[i]);
// 保存LIS的数组
int[] temp = new int[data.length];
temp[0] = d[0];// 先去第一个元素给temp[0],那么len自然就是1
int len = 1;
/*
* 输入例子 5 3 4 8 6 7
*/
for (int i = 1; i < temp.length; i++) {
int left = 0, right = len;
while (left <= right) {
int mid = (left + right) >> 1;
// 二分查找d[i]的插入位置
if (temp[mid] < d[i])
left = mid + 1;
else
right = mid - 1;
}
temp[left] = d[i];
// 当left大于len了,那么说明有新元素插入,要+1
len = left > len ? len + 1 : len;
}
//输出子序列,0不算
for (int i = 0; i < temp.length; i++) {
System.out.print(temp[i] + " ");
}
System.out.println("\n" + len);
}
}