P1064 [NOIP2006 提高組] 金明的預算方案 題解

XuOuXiao1024發表於2024-05-18

分析

每一套物品有主件和附件,主件可以單獨購買,附件只能和主件一起買。所以,每一套物品有四種買法:主件、主件和附件1、主件和附件2、主件和所有附件。
\(dp_j=\max(dp_j,dp_{j-v_{i_1}}+w_{i_1},dp_{j-v_{i_1}-v_{i_2}}+w_{i_1}+w_{i_2},dp_{j-v_{i_1}-v_{i_3}}+w_{i_1}+w_{i_3},dp_{j-v_{i_1}-v_{i_2}-v_{i_3}}+w_{i_1}+w_{i_2}+w_{i_3})\)

程式碼

#include<bits/stdc++.h>
using namespace std;
const int BUFSIZE=1<<20;
char ibuf[BUFSIZE],*is=ibuf,*it=ibuf;
char getc(){
    if(is==it)
        it=(is=ibuf)+fread(ibuf,1,BUFSIZE,stdin);
    return is==it?EOF:*is++;
}
int reads(){
    int ret=0;
    bool sign=0;
    char ch=getc();
    while(!isdigit(ch)){
        sign|=ch=='-';
        ch=getc();
    }
    while(isdigit(ch)){
        ret=ret*10+ch-'0';
        ch=getc();
    }
    return sign?-ret:ret;
}
int n,m,v[100][4],w[100][4],dp[40000];
int a,b,c;
int main(){
    m=reads(),n=reads();
    int j=0;
    for(int i=1;i<=n;i++){
        a=reads(),b=reads(),c=reads();
        if(c==0){
            v[i][++v[i][0]]=a;
            w[i][++w[i][0]]=a*b;
        }
        else{
            v[c][++v[c][0]]=a;
            w[c][++w[c][0]]=a*b;
        }
    }
    for(int i=1;i<=n;i++){
        for(int k=m;k>=v[i][1];k--){
            dp[k]=max(dp[k],dp[k-v[i][1]]+w[i][1]);
            if(k>=v[i][1]+v[i][2]) dp[k]=max(dp[k],dp[k-v[i][1]-v[i][2]]+w[i][1]+w[i][2]);
            if(k>=v[i][1]+v[i][3]) dp[k]=max(dp[k],dp[k-v[i][1]-v[i][3]]+w[i][1]+w[i][3]);
            if(k>=v[i][1]+v[i][2]+v[i][3]) dp[k]=max(dp[k],dp[k-v[i][1]-v[i][2]-v[i][3]]+w[i][1]+w[i][2]+w[i][3]);
        }
    }
    cout<<dp[m];
    return 0;
}

相關文章