输入包括两行,第一行两个整数n(0<=n<=1000)代表数组长度和aim(0<=aim<=5000),第二行n个不重复的正整数,代表arr。
输出一个整数,表示组成aim的最小货币数,无解时输出-1.
3 20 5 2 3
4
20=5*4
3 0 5 2 3
0
2 2 3 5
-1
时间复杂度,空间复杂度
。
import java.io.*; import java.util.Arrays; public class Main{ public static void main(String[] args) throws IOException{ BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String[] str = reader.readLine().split(" "); int[] arr = parse(str,2); int n = arr[0]; int amount = arr[1]; arr = parse(reader.readLine().split(" "),n); reader.close(); System.out.println(coinChange(arr,amount)); } private static int coinChange(int[] coins, int amount) { int max = amount + 1; int[] dp = new int[amount + 1]; Arrays.fill(dp, max); dp[0] = 0; for (int i = 1; i <= amount; i++) { for (int j = 0; j < coins.length; j++) { if (coins[j] <= i) { dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1); } } } return dp[amount] > amount ? -1 : dp[amount]; } private static int[] parse(String[] str,int len){ int[] arr = new int[len]; for(int i= 0;i < len;++i){ arr[i] = Integer.parseInt(str[i]); } return arr; } }
转化为完全背包:
aim--->背包容量
每种货币的面值--->每种物品的体积
货币数--->每种物品的价值
问题就转为:求背包容量恰好为 aim 时的最小价值
因为是恰好,所以初始化dp时要置为无穷,dp[0] = 0
import java.util.Arrays; import java.util.Scanner; public class Main { static int INF = Integer.MAX_VALUE >> 1; static int N = 5010; static int n, aim; static int[] g = new int[N]; static int[] dp = new int[N]; public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); aim = sc.nextInt(); Arrays.fill(dp, INF); dp[0] = 0; for (int i = 0; i < n; i++) { g[i] = sc.nextInt(); for (int j = g[i]; j <= aim; j++) { dp[j] = Math.min(dp[j], dp[j - g[i]] + 1); } } if (dp[aim] == INF) dp[aim] = -1; System.out.println(dp[aim]); } }
import java.util.*; public class P189 { public static int process(int[] arr, int N, int aim) { int[] dp = new int[aim + 1]; Arrays.fill(dp, -1); dp[0] = 0; for (int i = N - 1; i >= 0; i--) { for (int rest = 0; rest <= aim; rest++) { if (rest - arr[i] >= 0 && dp[rest - arr[i]] != -1) { if (dp[rest] != -1) { dp[rest] = Math.min(dp[rest], dp[rest - arr[i]] + 1); } else { dp[rest] = dp[rest - arr[i]] + 1; } } } } return dp[aim]; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int N = sc.nextInt(); int aim = sc.nextInt(); int[] arr = new int[N]; for (int i = 0; i < N; i++) { arr[i] = sc.nextInt(); } System.out.println(process(arr, N, aim)); } }