楼天城男人八题——POJ1742 Coins

题目链接
传说中楼教主的做男人不易八题之一,这题多重背包应该算最简单的一道了
我AC的时候Users (Solved) 有3945了。

关于背包问题可以看 dd_engi 大牛的【背包九讲】
看完01背包、完全背包和多重背包三个问题的解法就会做了
本题就是多重背包

java实现如下:

import java.util.Arrays;
import java.util.Scanner;
public class Main {

    static int n, m, re, count[], val[], dp[];

    //01背包
    static void f_01(int cost, int val) {
        for (int i = m; i >= cost; i--)
            dp[i] = Math.max(dp[i], dp[i - cost] + val);
    }

    //完全背包
    static void f_full(int cost, int val) {
        for (int i = cost; i <= m; i++)
            dp[i] = Math.max(dp[i], dp[i - cost] + val);
    }

    //多重背包
    static void f_mul(int cost, int val, int count) {
        if (count \* cost >= m) {
            f_full(cost, val);
        } else {
            int k = 1;
            while (k < count) {
                count -= k;
                f_01(k \* cost, k \* val);
                k \*= 2;
            }
            f_01(count \* cost, count * val);
        }
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        for (;;) {
            n = sc.nextInt();
            m = sc.nextInt();
            if (m + n == 0)
                return;
            re = 0;
            dp = new int[m + 1];
            //除dp[0]初始化为0外,其他初始化为-∞
            Arrays.fill(dp, 1, dp.length, Integer.MIN_VALUE);
            val = new int[n + 1];
            count = new int[n + 1];
            for (int i = 1; i <= n; i++)
                val[i] = sc.nextInt();
            for (int i = 1; i <= n; i++)
                count[i] = sc.nextInt();
            for (int i = 1; i <= n; i++)
                f_mul(val[i], val[i], count[i]);
            for (int i = 1; i <= m; i++)
                if (dp[i] == i)
                    re++;
            System.out.println(re);
        }
    }
}

你可能感兴趣的:(楼天城男人八题——POJ1742 Coins)