POJ 1276 Cash Machine

题目链接:POJ 1276 Cash Machine

题目大意:

题解:
多重背包模板题,需要用到二进制拆分,将物品数\(n_i\)拆成\(1,2,4,8,...,2^{k},x(x \leq 2^{k + 1})\),则这些数的组合可以表示\([1,n_i]\)的所有数,就不需要循环从\(1\)跑到\(n_i\)了。

#include <cstring>
#include <iostream>
using namespace std;
#define N 110

int dp[100010], cash, n, cnt, ni, di;
struct Node {
    int w, v;
} node[110];

void addNode(int n, int d) {
    int p = 1;
    while (n) {
        if (n >= p) {
            node[++cnt].w = d * p;
            node[cnt].v = d * p;
            n -= p;
            p <<= 1;
        } else {
            node[++cnt].w = d * n;
            node[cnt].v = d * n;
            n = 0;
        }
    }
}

int main() {
    while (cin >> cash >> n) {
        memset(dp, 0, sizeof(dp));
        cnt = 0;
        for (int i = 1; i <= n; ++i) {
            cin >> ni >> di;
            addNode(ni, di);
        }
        for (int i = 1; i <= cnt; ++i) {
            for (int j = cash; j >= node[i].w; --j) {
                dp[j] = max(dp[j], dp[j - node[i].w] + node[i].v);
            }
        }
        cout << dp[cash] << endl;
    }
    return 0;
}
posted @ 2022-01-29 21:27  ZZHHOOUU  阅读(33)  评论(0编辑  收藏  举报