救命,20pts求调

P1064 [NOIP2006 提高组] 金明的预算方案

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;
}

|