1、换零钱
package dynamicPrograming;
import java.util.Scanner;
//题目:给定数组a,a中所有数均为正数,每一个值代表一种面值,且只有一张,再给定一个正整数aim代表要找的钱数,问有多少种不同的换钱方法。
//经典的动态规划方法都是将动态规划表建立起来,动态规划表均是n行aim+1列,首先确定表的边界的值(即第一行与第一列的值),再分析dp[i][j]的值。
//分析出:d[i][j]=d[i-1][j]+(j-a[i]?d[i-1][j-a[i]]:0)
//时间复杂度为O(n*aim) 空间复杂度 为O(n*aim)
public class ChangeMoney
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int n =sc.nextInt();
int[] a =new int[n];
for(int i=0;i=0 ? dp[i-1][j-a[i]]:0;
}
}
// 查看一下dp表:
for(int i=0;i
2、换零钱
package dynamicPrograming;
import java.util.Scanner;
//题目:给一个数组,值都为正数且不重复,每个值代表一种面值的纸币,每种面值的纸币可以使用任意张,再给定一个整数aim代表要找的钱数,求组成aim的最少货币张数。不能组成返回-1.
public class ChangeMoney2
{
public static void main(String[] args)
{
// 输入再做一做,做成数组 靠控制台输入 aim 也是控制台输入
int[] arr = {1,4,16,64};
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
int aim = 1024;
System.out.println(minCoin(arr,aim-n));
}
public static int minCoin(int[] arr,int aim) {
if(arr==null||arr.length==0||aim<0) {
return -1;
}
int n = arr.length;
int max = Integer.MAX_VALUE;
int[][] dp= new int [n][aim+1];
// 给dp矩阵的第一行赋值,第一列的值就全为0,不用改了,初始化就已经赋了0
for(int j = 1; j <= aim; j++) {
dp[0][j] = max;
if(j-arr[0] >= 0 && dp[0][j-arr[0]] != max) {
dp[0][j] = dp[0][j-arr[0]]+1;
}
}
int left=0;
for(int i = 1;i < n; i++) {
for(int j = 1; j <= aim; j++) {
left = max ;
if(j - arr[i] >= 0 && dp[i][j-arr[i]] != max) {
left = dp[i][j-arr[i]] + 1;
}
dp[i][j] = Math.min(left,dp[i-1][j]);
}
}
return dp[n-1][aim] != max ? dp[n-1][aim]: -1;
}
}
3、换零钱
package dynamicPrograming;
//题目:给定数组arr。arr中所有的数全为正数,每个数代表一张钱的面值,再给一个整数aim,代表要换的钱数,求组成aim的最少货币张数
public class ChangeMoney3
{
public static void main(String[] args)
{
int[] arr= {5,2,5,3};
int aim =10;
System.out.println(minCoin3(arr,aim));
}
public static int minCoin3(int[] arr,int aim) {
if(arr==null||arr.length==0||aim<0) {
return -1;
}
int n = arr.length;
int max = Integer.MAX_VALUE;
int[][] dp = new int[n][aim+1];
for(int j=1;j= 0 && dp[i-1][j-arr[i]] != max) {
leftup = dp[i-1][j-arr[i]]+1;
}
dp[i][j] = Math.min(leftup,dp[i-1][j]);
}
}
return dp[n-1][aim] != max ? dp[n-1][aim] : -1;
}
}
4、换零钱,空间优化:一维数组的更新
package dynamicPrograming;
import java.util.Scanner;
//对额外空间进行压缩,额外空间复杂度由O(n*aim)变为O(aim)
//原始dp表:d[i][j]=d[i-1][j]+(j-a[i]?d[i-1][j-a[i]]:0)
//按行更新:d[j]=d[j]+(j-a[i]>=0?d[j-a[i]]:0 表示此刻的值d[j]由上一行的值确定,
public class ChangeMoneyOptimization
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int n =sc.nextInt();
int[] a =new int[n];
for(int i=0;i=0;j--)
{d[j]=d[j]+(j-a[i]>=0?d[j-a[i]]:0);
}
}
return d[aim];
}
}