alxdsptr @ 2023-08-09 00:40:24
大概思路是在遇到主件的时候复制一个dp数组出来然后先选上主件,然后附件正常dp,然后挨个比较新的dp数组和原来的取最大
#include <iostream>
#include <cstring>
using namespace std;
#define maxN 3205
#define maxM 60
struct thing{
int v, p, sub[2], index = 0;
bool dom = false;
} th[maxM];
int dp[maxN];
int main(){
int n, m, i, j, tmp;
cin >> n >> m;
n /= 10;
for(i = 0; i < m; i++){
cin >> th[i].v >> th[i].p >> tmp;
th[i].v /= 10;
if(tmp == 0){
th[i].dom = true;
}else{
tmp = tmp - 1;
th[tmp].sub[th[tmp].index] = i;
th[tmp].index++;
}
}
for(j = 0; j < m; j++){
if(th[j].dom){
int val = th[j].v, tot = th[j].v * th[j].p;
if(th[j].index == 0){
for(int k = n; k >= val; k--){
dp[k] = max(dp[k], dp[k - val] + tot);
}
}else{
int temp[maxN];
memcpy(temp + val, dp, (n - val + 1) * sizeof(int));
for(int k = n; k >= val; k--){
temp[k] += tot;
}
for(int l = 0; l < th[j].index; l++){
int idx = th[j].sub[l];
for(int k = n; k >= th[idx].v + val; k--){
temp[k] = max(temp[k], temp[k - th[idx].v] + th[idx].v * th[idx].p);
}
}
for(int k = val; k <= n; k++){
dp[k] = max(dp[k], temp[k]);
}
}
}
}
cout << dp[n] * 10;
}