不知道哪里错了,请dalao看看

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

信赖滴星辰 @ 2019-03-27 14:10:28

题解的方法太烦了,有个新思路,但是样例都过不了……

#include <iostream>
using namespace std;

int T,n;
int t[104],v[104],q[104],ans[104],f[32004],check[104];

int main()
{
    cin>>T>>n;

    for(int i=1;i<=n;i++) cin>>v[i]>>t[i]>>q[i];

    for(int i=1;i<=n;i++) ans[i]=v[i]*t[i];

    for(int i=1;i<=n;i++)
    {
        for(int j=T;j>=v[i];j--)
        {
            if(q[i]==0) 
            {
                if( f[j] > (f[j-v[i]]+ans[i]) ) f[j]=f[j-v[i]]+ans[i],check[i]=1;
                else check[i]=0;
            }

            if(q[i]>0)
            {
                if(check[q[i]]==1) f[j]=max( f[j] , f[j-v[i]]+ans[i] );
                else continue;
            }

        }
    }

    cout<<f[T]<<endl;

return 0;   
}

主要思路就是加一个判断是否选取过的数组check,如果选到附件,判断它的主件是否被选取过,如果选取过则用动归判断是否符合利益最大化。

但是样例输出了0


by SkyLiYu @ 2019-03-27 14:51:32

@信赖滴星辰 这思路听上去正确性并不靠谱


by 信赖滴星辰 @ 2019-03-27 14:54:07

@隔壁小邱 why?


by SkyLiYu @ 2019-03-27 14:55:23

@信赖滴星辰 我想想反例,别急(毕竟我很弱


by SkyLiYu @ 2019-03-27 14:57:23

@信赖滴星辰 你在装的时候主副件是有顺序的,可能你压根还没有循环到主件,就循环到了附件,这样你的附件就没有选


by SkyLiYu @ 2019-03-27 14:58:26

@信赖滴星辰 你这样装最起码你得改变初始读入数组的顺序然而改变顺序正确性也不一定对


by 信赖滴星辰 @ 2019-03-27 15:04:55

@隔壁小邱 我知道了,这样并不能保证是最优解,因为前面一个主件不选有可能是前面的局部最优解,但不是总体最优解


by SkyLiYu @ 2019-03-27 15:07:25

@信赖滴星辰 没错(然而我说的重点不是这个,你这个是全局最优性无法保证,而你的代码本身正确性就无法保证)算了,总之你知道这个写法不对就可以了


|