挂饰 BZOJ

来源:互联网 发布:dchp mac地址 时间 编辑:程序博客网 时间:2024/06/07 02:14

题目传送门

思路:一个背包问题,这个背包问题和一般的背包问题不同的是这个背包的容量是可以变化的,所有我们定义DP[i][j]代表安装i挂钩以后还剩下j个挂钩,然后递推式就是dp[i][j] = max(dp[i - 1][j], dp[i - 1][max(j - p[i].a, 0) + 1] + p[i].b)

#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <list>#include <map>#include <queue>#include <set>#include <stack>#include <string>#include <vector>#define MAXN 4010#define MAXE 5#define INF 2100000000#define MOD 100003#define LL long long#define ULL unsigned long long#define pi 3.14159using namespace std;struct Node {    int a;    int b;}p[MAXN];bool cmp(const Node &p1, const Node &p2) {    return p1.a > p2.a;}LL dp[MAXN][MAXN];int main() {    //std::ios::sync_with_stdio(false);    int n;    scanf("%d", &n);    for (int i = 1; i <= n; ++i) {        scanf("%d%d", &p[i].a, &p[i].b);    }    sort(p + 1, p + n + 1, cmp);    for (int i = 0; i <= n; ++i) {        for (int j = 0; j <= n + 1; ++j) {            dp[i][j] = -INF;       }    }    dp[0][1] = 0;    for (int i = 1; i <= n; ++i) {        for (int j = 0; j <= n; ++j) {            dp[i][j] = max(dp[i - 1][j], dp[i - 1][max(j - p[i].a, 0) + 1] + p[i].b);        }    }    LL max_sum = 0;    for (int i = 0; i <= n; ++i) {        max_sum = max(max_sum, dp[n][i]);    }    printf("%lld\n", max_sum);    return 0;}