求教 标准的分类+dp只有50分……

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

luyan @ 2018-12-03 21:54:32

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[61][32001];//对于前i个物品花费j元可以得到的最大重要度 
int pri[61][3],imp[61][3];//价格  重要度
//动归分五类:不取 只取主键,1号附件和主件,2号附件和主件,1、2和主件 
int main(){
    memset(pri,-1,sizeof(pri));
    memset(imp,-1,sizeof(imp));
    memset(dp,0,sizeof(dp));
    int n,m;
    cin>>m>>n;
    int c=1;
    for(int i=1;i<=n;i++){
        int v,p,q;
        cin>>v>>p>>q;//价格、重要度、附件还是主件
        if(q==0){
            pri[c][0]=v;
            imp[c++][0]=p;
        }
        else if(pri[q][1]==-1){
            pri[q][1]=v;
            imp[q][1]=p;
        }
        else {
            pri[q][2]=v;
            imp[q][2]=p;
        }
    }
    c-=1;
    for(int i=1;i<=c;i++){
        for(int j=1;j<=m;j++){
            if(j>=pri[i][0]){
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-pri[i][0]]+(pri[i][0]*imp[i][0]));
                if(pri[i][1]!=-1&&j>=pri[i][0]+pri[i][1]){
                    dp[i][j]=max(dp[i][j],dp[i-1][j-pri[i][1]-pri[i][0]]+(imp[i][0]*pri[i][0])+(imp[i][1]*pri[i][1]));
                }
                if(pri[i][2]!=-1&&j>=pri[i][0]+pri[i][2]){
                    dp[i][j]=max(dp[i][j],dp[i-1][j-pri[i][0]-pri[i][2]]+(imp[i][0]*pri[i][0])+(imp[i][2]*pri[i][2]));
                }
                if(pri[i][1]!=-1&&pri[i][2]!=-1&&j>=(pri[i][0]+pri[i][1]+pri[i][2])){
                    dp[i][j]=max(dp[i][j],dp[i-1][j-pri[i][0]-pri[i][1]-pri[i][2]]+(pri[i][0]*imp[i][0])+(pri[i][1]*imp[i][1])+(pri[i][2]*imp[i][2]));
                }
            }
            else dp[i][j]=dp[i-1][j];
        }
        cout<<dp[i][m]<<endl;
    }
    int ans=-1;
    for(int i=1;i<=c;i++)ans=max(ans,dp[i][m]);
    cout<<ans<<endl;
} 

|