中文题。
不难发现这是一道有依赖的背包,但是如果根据之前有依赖的背包模版去做会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; }