P1833 樱花 背包DP 多重背包 , 混合背包

混合背包是指很多种背包一起做。此题属于多重背包的模板题

思想是统统转化为01背包

题目中有01背包(p = 1),完全背包(p = 0)  , 多重哦背包 (p = k)

完全背包,只需将p = t / w 。

多重背包,只需进行二进制拆分

注意数组开大

int readint() {
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

ll readll() {
    ll x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

void Put(int x)  {
    if (x > 9) Put(x / 10);
    putchar(x % 10 + '0');
}

int dp[maxn];
int val[maxn];
int w[maxn];
int p[maxn];

int main() {
    int t1, t2, t3, t4, n;
    scanf("%d:%d %d:%d %d", &t1, &t2, &t3, &t4, &n);
    int t = (t1 * 60 + t2 );
    t = -1 * t + (t3 * 60 + t4 );
    for (int i = 0; i < n; i++) w[i] = readint(), val[i] = readint(), p[i] = readint();
    int tot = n - 1;
    for (int i = 0; i < n; i++) {
        if (p[i] == 1) continue;
        if (!p[i]) p[i] = t / w[i] + 2;
        int _p = p[i] - 1;
        for (int j = 2; j <= _p; j <<= 1) {
            _p -= j;
            w[++tot] = j * w[i];
            val[tot] = j * val[i];
        }
        if (_p) {
            w[++tot] = _p * w[i];
            val[tot] = _p * val[i];
        }
    }
    for (int i = 0; i <= tot; i++) {
        for (int j = t; j >= w[i]; j--) {
            dp[j] = max(dp[j], dp[j - w[i]] + val[i]);
        }
    }
    Put(dp[t]);
}

猜你喜欢

转载自www.cnblogs.com/hznumqf/p/13405754.html