POJ1276 Cash Machine(多重背包)

题目链接

分析:

该题为多重背包。

有了上一次的经验(HDU2191),这道题也就了了了。

本题的思路:

将cash想象成包的容量,将面值Dk想象成两个条件,即体积和价值都为Dk,那么本题就自然而然的成了求最大价值的问题。

另外,这次尝试了一下其它的代码风格,因为曾经听说过,试了一下,写起来感觉不错,但找起来错就不那么容易了。

纠结#define For(i, i0, n) for(int i=i0; i<=n; i++),是将它定义成i<=n呢还是i<n呢?在敲代码的过程中错认为是i<n,找了很久BUG。

#include <cstdio>
#include <cstring>
#include <cstdlib>

#define For(i, i0, n) for(int i=i0; i<=n; i++)
#define Forx(i, n, i0) for(int i=n; i>=i0; i--)
#define scad(n) scanf("%d", &n)
#define scas(s) scanf("%s", s)
#define Memset(p) memset(p, 0, sizeof(p))

int dp[100010];

int main(){
    int cash, n, p, d;
    while(scad(cash) == 1){
        For(i, 0, cash) dp[i] = 0;
        scad(n);
        For(i, 0, n-1){
            scad(d); scad(p);
            if(d * p >= cash){
                For(j, 0, cash){
                    if(j+p<=cash && dp[j+p] < dp[j]+p)
                        dp[j+p] = dp[j]+p;
                }
            }
            else{
                int k=1;
                while(d){
                    if(k > d) k = d;
                    d -= k;
                    Forx(j, cash, k*p){
                        if(dp[j] < dp[j-k*p]+k*p)
                            dp[j] = dp[j-k*p]+k*p;
                    }
                    k <<= 1;
                }
            }
        }
        printf("%d\n", dp[cash]);
    }
}
原文地址:https://www.cnblogs.com/tanhehe/p/3002147.html