P1064 金明的预算方案

中文题。

 

不难发现这是一道有依赖的背包,但是如果根据之前有依赖的背包模版去做会TLE。

再仔细看一下题,不难发现它必定是二叉树的树型结构的,所以我们对于它的每种情况我们其实是可以枚举出来的。

1、取父亲

2、取父亲、左儿子

3、取父亲、左儿子、右儿子

4、取父亲、右儿子

 

#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>
#include <cstring>

#define LL long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back

const double eps = 1e-10;
const int maxn = 4e4 + 10;
const LL mod = 1e9 + 7;
const LL INF = 1e18;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

struct node{
    int v,w;
};

int f[maxn];
struct node ipm[maxn][3];
int t[maxn];

int main() {
    ios::sync_with_stdio(false);
    int n,m;
    cin >> n >> m;
    for (int i = 1;i <= m;i++) {
        int v,p,q;
        cin >> v >> p >> q;
        if (!q) {
            ipm[i][2].v = v;
            ipm[i][2].w = v * p;
        }
        else {
            ipm[q][t[q]].v = v;
            ipm[q][t[q]].w = v * p;
            t[q]++;
        }
    }
    for (int i = 1;i <= m;i++) {
        for (int j = n;j >= ipm[i][2].v;j--) {
            f[j] = max(f[j],f[j-ipm[i][2].v]+ipm[i][2].w);
            if (j >= ipm[i][2].v+ipm[i][0].v) {
                f[j] = max(f[j],f[j-(ipm[i][2].v+ipm[i][0].v)]+(ipm[i][2].w+ipm[i][0].w));
            }
            if (j >= ipm[i][2].v+ipm[i][1].v) {
                f[j] = max(f[j],f[j-(ipm[i][2].v+ipm[i][1].v)]+ipm[i][2].w+ipm[i][1].w);
            }
            if (j >= ipm[i][2].v+ipm[i][1].v+ipm[i][0].v) {
                f[j] = max(f[j],f[j-(ipm[i][2].v+ipm[i][1].v+ipm[i][0].v)]+ipm[i][2].w+ipm[i][1].w+ipm[i][0].w);
            }
        }
    }
    cout << f[n] << endl;
    return 0;
}

 

posted @ 2020-03-09 21:21  _Ackerman  阅读(152)  评论(0编辑  收藏  举报