20分不知道错哪的可以来看一眼,大佬也来看一眼吧

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

polari @ 2023-08-09 21:38:20

我辛苦写的注释不能让它白费是吧

感觉我的代码已经完美契合要考的东西了,思路清晰

然后20分,其他wa

自己查不出错

#include<bits/stdc++.h>
using namespace std;
int n,m;
int num[120],fu[120][4];//存附件数 
int co[120],va[120],bo[120];//存相关量(cost消耗值,value重要度,判断是否为主件(能不能直接取) 
int f[640000];// 
int main()
{
    cin>>n>>m;
    memset(num,0,sizeof(num));
    for(int i=1;i<=m;i++)
    {
        int c=0;
        cin>>co[i]>>va[i]>>c;
        if(c!=0)
        {
            num[c]++;
            fu[c][num[c]]=i;
            bo[i]=1;
        }
    }
    for(int i=1;i<=m;i++)
        if(bo[i]==0)//以主件为前提
        {
            for(int j=n;j>=co[i];j--)//主件都可以单独买 
                f[j]=max(f[j],f[j-co[i]]+co[i]*va[i]);
            if(num[i]>=1)//如果有一个以上附件 
            {
                for(int j=n;j>=co[i]+co[fu[i][1]];j--)//选第一个 
                    f[j]=max(f[j],f[j-co[i]-co[fu[i][1]]]+co[i]*va[i]+co[fu[i][1]]*va[fu[i][1]]);
                if(num[i]==2)//如果两个附件 
                {
                    for(int j=n;j>=co[i]+co[fu[i][2]];j--)//选第二个 
                        f[j]=max(f[j],f[j-co[i]-co[fu[i][2]]]+co[i]*va[i]+co[fu[i][2]]*va[fu[i][2]]);
                    for(int j=n;j>=co[i]+co[fu[i][1]]+co[fu[i][2]];j--)//都选 
                        f[j]=max(f[j],f[j-co[i]-co[fu[i][1]]-co[fu[i][2]]]+co[i]*va[i]+co[fu[i][1]]*va[fu[i][1]]+co[fu[i][2]]*va[fu[i][2]]); 
                }
            }
        }
    cout<<f[n];
    return 0;
}

后来看题解思路也一样 对比了半天终于发现问题

大概 我是逐层判断他是几个附件 因为两个附件的选法也包含0,1个的选法 节省了码量

我觉得问题出在我这样写会同一个经历多个n到最小cost,会多次取到主件.

把多个for循环去掉 只留最外面一个 改成判断j的大小能否取来分出几种情况

ac码就不贴了,毕竟讨论区

理解有错还请大佬指出

如果我翻讨论区时有人和我错一样就好了(悲)

以上

引以为戒


|