背包DP泛做

Posted 23forever

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了背包DP泛做相关的知识,希望对你有一定的参考价值。

DP太弱了,要多做。
结果做了一堆傻逼题。。。

洛谷P2639:

01背包

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define max(a, b) (a < b ? b : a)
const int MAXN = 500;
using namespace std;

inline int read() {
    int x = 0, w = 1;
    char c = ‘ ‘;

    while (c < ‘0‘ || c > ‘9‘) {
        c = getchar();
        if (c == ‘-‘) w = -1;
    }
    while (c >= ‘0‘ && c <= ‘9‘) {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }

    return x * w;
}

int n, m, dp[45000 + 5], a[MAXN + 5];

void init() {
    m = read();
    n = read();

    for (int i = 1; i <= n; ++i) 
        a[i] = read();
}

int main() {
    init();
    
    for (int i = 1; i <= n; ++i)
        for (int j = m; j >= a[i]; --j)
            dp[j] = max(dp[j - a[i]] + a[i], dp[j]);

    printf("%d\n", dp[m]);

    return 0;
}

洛谷P2722

#include <iostream>
#include <cstdio>
const int MAXN = 10000;
using namespace std;

inline int read() {
    int x = 0, w = 1;
    char c = ‘ ‘;

    while (c < ‘0‘ || c > ‘9‘) {
        c = getchar();
        if (c == ‘-‘) w = -1;
    }
    while (c >= ‘0‘ && c <= ‘9‘) {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }

    return x * w;
}

struct Node {
    int num, t;
}a[MAXN + 5];

int n, m, dp[MAXN + 5];

void init() {
    m = read();
    n = read();

    for (int i = 1; i <= n; ++i) {
        a[i].num = read();
        a[i].t = read();
    }
}

int main() {
    init();
 
    for (int i = 1; i <= n; ++i) 
        for (int j = a[i].t; j <= m; ++j)
            dp[j] = max(dp[j - a[i].t] + a[i].num, dp[j]);

    printf("%d\n", dp[m]);

    return 0;
}

洛谷P2347:

多重背包,有bitset水法。

#include <iostream>
#include <cstdio>
#include <bitset>
const int MAXN = 1000;
using namespace std;

inline int read() {
    int x = 0, w = 1;
    char c = ‘ ‘;

    while (c < ‘0‘ || c > ‘9‘) {
        c = getchar();
        if (c == ‘-‘) w = -1;
    }
    while (c >= ‘0‘ && c <= ‘9‘) {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }

    return x * w;
}

int n = 6, m = 1000, dp[MAXN + 5];
int w[MAXN + 5] = {0, 1, 2, 3, 5, 10, 20}, a[MAXN + 5]; 

bitset < 1001 > S;

void init() {
    for (int i = 1; i <= n; ++i)
        a[i] = read();

    S[0] = 1;
}

int main() {
    init();

    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= a[i]; ++j)
            S |= S << w[i];
        
    printf("%d\n", S.count() - 1);

    return 0;
}

洛谷P2925:

#include <iostream>
#include <cstdio>
const int MAXN = 50000;
using namespace std;

inline int read() {
    int x = 0, w = 1;
    char c = ‘ ‘;

    while (c < ‘0‘ || c > ‘9‘) {
        c = getchar();
        if (c == ‘-‘) w = -1;
    }
    while (c >= ‘0‘ && c <= ‘9‘) {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }

    return x * w;
}

int n, m, dp[MAXN + 5];
int a[MAXN + 5];

void init() {
    m = read();
    n = read();

    for (int i = 1; i <= n; ++i)
        a[i] = read();
}

int main() {
    init();
    
    for (int i = 1; i <= n; ++i)
        for (int j = m; j >= a[i]; --j)
            dp[j] = max(dp[j - a[i]] + a[i], dp[j]);

    printf("%d\n", dp[m]);

    return 0;
}

洛谷P1910

#include <iostream>
#include <cstdio>
const int MAXN = 100;
using namespace std;

inline int read() {
    int x = 0, w = 1;
    char c = ‘ ‘;

    while (c < ‘0‘ || c > ‘9‘) {
        c = getchar();
        if (c == ‘-‘) w = -1;
    }
    while (c >= ‘0‘ && c <= ‘9‘) {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }

    return x * w;
}

struct Node {
    int a, b, c;
}a[MAXN + 5];

int dp[1000 + 5][1000 + 5], n, m, x;

void  init() {
    n = read();
    m = read();
    x = read();

    for (int i = 1; i <= n; ++i) {
        a[i].a = read();
        a[i].b = read();
        a[i].c = read();
    }
}

int main() {
    init();

    for (int i = 1; i <= n; ++i)
        for (int j = m; j >= a[i].b; --j)
            for (int k = x; k >= a[i].c; --k)
                dp[j][k] = max(dp[j - a[i].b][k - a[i].c] + a[i].a, dp[j][k]);
    
    printf("%d\n", dp[m][x]);

    return 0;
}

洛谷P1734

#include <iostream>
#include <cstdio>
const int MAXN = 1000;
using namespace std;

inline int read() {
    int x = 0, w = 1;
    char c = ‘ ‘;

    while (c < ‘0‘ || c > ‘9‘) {
        c = getchar();
        if (c == ‘-‘) w = -1;
    }
    while (c >= ‘0‘ && c <= ‘9‘) {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }

    return x * w;
}

int n, a[MAXN + 5], dp[MAXN + 5];

void init() {
    n = read();

    for (int i = 1; i <= n; ++i) 
        for (int j = 1; j < i; ++j)
            if (i % j == 0) a[i] += j;
} 

int main() {
    init();
    
    for (int i = 1; i <= n; ++i)
        for (int j = n; j > i; --j)
            dp[j] = max(dp[j - i] + a[i], dp[j]);

    printf("%d\n", dp[n]);

    return 0;
}

以上是关于背包DP泛做的主要内容,如果未能解决你的问题,请参考以下文章

AC自动机+DP泛做

UOJ泛做

USACO泛做

背包dp总结

dp背包问题

被遗忘的DP -01背包代码