我快疯了,pts40,求调

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

zengqhuai @ 2023-07-18 10:18:18

#include<bits/stdc++.h>
using namespace std;
int dp[85][10005]={},n,zu[85][5],cost[85],vlu[85],money,zu_i_sum[85]={},zu_sum=0;
int main()
{
    cin>>money>>n;
    for(int i=1,l=1;l<=n;i++,l++){
        int z,v;
        cin>>cost[i]>>v>>z;
        vlu[i]=v*cost[i];
        if(z!=0){
            cost[i]+=cost[z+(i-l)];
            vlu[i]+=vlu[z+(i-l)];
            zu_i_sum[z]++;
            zu[z][zu_i_sum[z]]=i;
            if(zu_i_sum[z]==3){
                i++;
                zu_i_sum[z]++;
                cost[i]=cost[zu[z][1]];
                vlu[i]=vlu[zu[z][1]];
                for(int j=2;j<=3;j++){
                    cost[i]+=cost[zu[z][j]]-cost[zu[z][1]];
                    vlu[i]+=vlu[zu[z][j]]-vlu[zu[z][1]];
                }
            }
        }
        else{
            zu_sum=max(zu_sum,l);
            zu_i_sum[l]++;
            zu[l][1]=i;
        }
    }
    for(int i=1;i<=zu_sum;i++){
        for(int j=1;j<=money;j++){
            dp[i][j] = max(dp[i][j], dp[i-1][j]);
            for(int k=1;k<=zu_i_sum[i];k++){
                if(j-cost[zu[i][k]]>=0){
                    dp[i][j]=max(dp[i][j],vlu[zu[i][k]]+dp[i-1][j-cost[zu[i][k]]]);
                }
            }
        }
    }
    cout<<dp[zu_sum][money];
    return 0;
}

by zengqhuai @ 2023-07-18 10:20:32

以为是分组背包,然后调了两天


by XUER_WANG @ 2023-07-18 10:58:13

可能是少判了两种附件都选的情况。

我写记忆化错了这点也是40,加上就过了(

900 7
200 4 0
500 2 4
100 3 1
100 1 2
500 3 1
400 5 3
100 1 6

这组数据答案应该是 2600 ,你的代码和我40的都是输出了 2300


by zengqhuai @ 2023-07-18 14:59:56

@XUER_WANG 虽然我是有特判

if(zu_i_sum[z]==3){
                i++;
                zu_i_sum[z]++;
                cost[i]=cost[zu[z][1]];
                vlu[i]=vlu[zu[z][1]];
                for(int j=2;j<=3;j++){
                    cost[i]+=cost[zu[z][j]]-cost[zu[z][1]];
                    vlu[i]+=vlu[zu[z][j]]-vlu[zu[z][1]];
                }
            }

但还是感谢dalao的数据 (ps:这附件能这样选是我没想到的)


|