多重背包转为一维背包 POJ1276
传统思路如下
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Scanner; import java.util.StringTokenizer; public class Main { public static void main(String[] args) throws Exception { // BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); Scanner sc = new Scanner(System.in); StringTokenizer st; while (sc.hasNextInt()) { // while (br.ready()) { // st = new StringTokenizer(br.readLine()); // int request = Integer.parseInt(st.nextToken()); // 取款机请求的现金 int request = sc.nextInt(); // 取款机请求的现金 // int N = Integer.parseInt(st.nextToken()); // 金额的种类 int N = sc.nextInt(); // 金额的种类 if(N == 0 && request == 0) break; int count[] = new int[N]; int val[] = new int[N]; for (int i = 0; i < N; i++) { // count[i] = Integer.parseInt(st.nextToken()); // 第i种类的金额个数 // val[i] = Integer.parseInt(st.nextToken()); // 第i种类的金额面值 count[i] = sc.nextInt(); // 第i种类的金额个数 val[i] = sc.nextInt(); // 第i种类的金额面值 } int[] dp = new int[request+1]; // 表示请求i金额最多输出得到实际金额 int cnt[] = new int[request+1]; // i金额使用货币得到个数 for (int i = 0; i < N; i++) { // 循环金额种类 cnt = new int[request+1]; for (int j = val[i]; j <= request; j++) { // 循环金额面值 if(dp[j] < dp[j - val[i]] + val[i] && cnt[j - val[i]] < count[i]) { dp[j] = dp[j - val[i]] + val[i]; cnt[j] = cnt[j - val[i]] + 1; } } } System.out.println(dp[request]); } } }

浙公网安备 33010602011771号