20分求助

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

Liu_Su_ @ 2024-11-20 21:13:31

1#10#12AC 其余WA

思路是将主,主+附一,主+附二,主加附一加附二放在一组中,然后同P1757 通天之分组背包类似的代码,cnt记组数,代码中有调试

#include<bits/stdc++.h>
using namespace std;
#define int long long
int m,n,cnt=0,sum=0,ans;
int dp[105][40005];
int fjw[1005],fjv[1005];
bool pd[1005];
struct node{
    int w,v,k;
}q[1005];
bool cmp(node q1,node q2){
    return q1.k<q2.k;
}
signed main(){
    cin>>m>>n;
    for (int i=1;i<=n;i++) {
        cin>>q[i].w>>q[i].v>>q[i].k;
        q[i].v*=q[i].w;
        if (q[i].k==0) q[i].k=i;
        else{
            if (pd[q[i].k]==1){
                q[i].w+=q[q[i].k].w;
                q[i].v+=q[q[i].k].v;
                sum++;
                q[n+sum].w=(fjw[q[i].k]+q[i].w);
                q[n+sum].v=(fjv[q[i].k]+q[i].v);
                q[n+sum].k=q[i].k;
            }else{
                fjw[q[i].k]=q[i].w;
                fjv[q[i].k]=q[i].v;
                q[i].w+=q[q[i].k].w;
                q[i].v+=q[q[i].k].v;
                pd[q[i].k]=1;
            }
        }
    }
    n+=sum;
    sort(q+1,q+n+1,cmp);
//  for (int i=1;i<=n;i++) cout<<q[i].w<<" "<<q[i].v<<" "<<q[i].k<<endl;
    for (int i=1;i<=n;i++){
        if (q[i].k!=q[i-1].k) cnt++;
//      cout<<q[i].k<<" "; 
        for (int j=0;j<=m;j++){
            if (j>=q[i].w){
                dp[cnt][j]=max(dp[cnt][j],dp[cnt-1][j-q[i].w]+q[i].v);
            }
            else dp[cnt][j]=max(dp[cnt-1][j],dp[cnt][j]);
        }
    }
    for (int i=1;i<=m;i++)
        ans=max(ans,dp[cnt][i]); 
    cout<<ans;
    return 0;
}

by Liu_Su_ @ 2024-11-20 21:14:39

写错点得分情况了,现在是30分,#1#3#10AC


by Ha_007 @ 2024-11-21 08:15:07

@LiuSu首先把

  dp[cnt][j]=max(dp[cnt][j],dp[cnt-1][j-q[i].w]+q[i].v);

改为

  dp[cnt][j]=max(max(dp[cnt][j],dp[cnt-1][j]),dp[cnt-1][j-q[i].w]+q[i].v);

然后题目并没有保证主件在附件之前,所以要把20-35行放到输入之后


by Liu_Su_ @ 2024-11-21 14:51:40

@Ha_007

A了A了,感谢大佬,%%%%%


|