2013/7/23

来源:互联网 发布:天刀曲无忆捏脸数据 编辑:程序博客网 时间:2024/06/04 22:52

HDOJ 2546饭卡

01背包,本题思路是将除去最大价格的菜,找出卡中剩余钱-5时,可购买的最大数目,然后用卡中剩余钱-最大数目-最大价格菜价格就是答案。

做这题的时候一直认为这种思路是错的,可能存在加上最大价格的菜恰好剩5元,然后减去次大价格的菜才是正解。其实将顺序换下,没有关系,所以这个思路成立。

PS:需考虑剩余价格小于5的情况



POJ1014 HDOJ1059Dividing

本题为多重背包,因数据量大,在处理完全背包部分,需用01背包2进制(V*∑logn[i])方法,否则会超时。//错了..

PS:一开始在POJ RE,数组开小了...

然后在HDOJ提交时出现RE...专题内提交显示RE,外面RE(堆栈溢出)

原因是大数组应该在main外面开...

结论:以后HDOJ专题什么的还是在外面交,HDOJ数组什么的在外面开,开大点...得意

发现重大失误,处理完全背包部分,复杂度是(V*N),超时是因为理解不透彻。实际写成了(∑N[i]*V)的复杂度了抓狂

附上错误代码

#include<stdlib.h>#include<math.h>int r[1000000];int main(){    int a[6],sum,i,j,k,num=1,dig;    memset(r,0,sizeof(r));    while(scanf("%d%d%d%d%d%d",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5]),a[0]+a[1]+a[2]+a[3]+a[4]+a[5])    {        sum=0;        if(num>1)printf("\n");        printf("Collection #%d:\n",num++);        for(i=0;i<6;i++)        sum=sum+a[i]*(i+1);        r[0]=1;        for(i=0;i<6;i++)        {            if(a[i]*(i+1)>=sum/2)            {              //  for(j=1;j<=a[i];j++)//此处为多余循环导致复杂度由N*V变为V*∑N[i]               // {                    for(k=i+1;k<=sum/2;k++)                    {                        if(r[k-i-1]==1)r[k]=1;                    }              //  }            }            if(r[sum/2]==1)break;            if(a[i]*(i+1)<sum/2)            {                k=1;dig=a[i];                while(k<dig)                {                    for(j=sum/2;j>=k*(i+1);j--)                    {                        if(r[j-(i+1)*k]==1)r[j]=1;                    }                    dig=dig-k;                    k=k*2;                }                for(j=sum/2;j>=dig*(i+1);j--)                    if(r[j-(i+1)*dig]==1)r[j]=1;            }        }        if(r[sum/2]==1)printf("Can be divided.\n");        else printf("Can't be divided.\n");        for(i=0;i<=sum;i++)            r[i]=0;    }    return 0;}