【DP】【01背包】【完全背包】Birthday 题解

来源:互联网 发布:手提旅行包 知乎 编辑:程序博客网 时间:2024/05/22 07:15

n个物品m元钱,每个物品给出单价、权值以及第一次购买时赠送的权值

其实就是01背包和完全背包套一起,解法其实写一个背包判一个也可以过

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <set>#include <queue>#include <algorithm>#include <vector>#include <cstdlib>#include <cmath>#include <ctime>#include <stack>#define INF 2147483647#define LL long long#define clr(x) memset(x, 0, sizeof x)#define digit (ch <  '0' || ch >  '9')using namespace std;template <class T> inline void read(T &x) {    int flag = 1; x = 0;    register char ch = getchar();    while( digit) { if(ch == '-')  flag = -1; ch = getchar(); }    while(!digit) { x = (x<<1)+(x<<3)+ch-'0'; ch = getchar(); }    x *= flag;}const int maxn = 2005;const int maxm = 4005;int n,m,c;int w[maxn],a[maxn],b[maxn],dp[maxn];int main() {    freopen("birthday.in","r",stdin);    freopen("birthday.out","w",stdout);    read(n); read(m);    for(register int i = 1; i <= n; i++) {        read(w[i]), read(a[i]), read(b[i]);        int flag = 0; a[i] += b[i];        for(register int j = m; j >= w[i]; j--) {            dp[j] = max(dp[j], dp[j-1]);            if(dp[j-w[i]]+a[i] > dp[j]) flag = 1, dp[j] = dp[j-w[i]]+a[i];        }        a[i] -= b[i];        if(flag == 1) for(register int j = w[i]; j <= m; j++) {            dp[j] = max(dp[j], dp[j-1]);            if(dp[j-w[i]]+a[i] > dp[j]) dp[j] = dp[j-w[i]]+a[i];        }    }    printf("%d",dp[m]);    return 0;}
原创粉丝点击