hdu 3732 Ahui Writes Word

时间:2023-03-08 17:15:38

这是一道背包题,当你题读完了的时候,你会觉得这道题明明就是01背包的完全版吗!

no no no no no no  no no  no no no~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;

~~~~~~~~~~~~~~~~~~~~~

对!不是,是,还是不是,是~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

好吧,这是一道01背包题,但按01背包做会超时,我之所以知道是因为我做过按01背包!

这道题的妙处在于转化为多重背包!,对,这就是这道题的妙处!我喜欢这道题的这一点!!!!

背包好久没看了!哎····,也忘得差不多了!!!

<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><<><<K<<><><><><><><<><><><><><><><><><><><<

#include<stdio.h>

#include<string.h>

#define max(a,b) a>b?a:b

int bb[500010],q,vv;

void shun(int cost,int weight)

{


int i;


for(i=cost;i<=vv;i++)


bb[i]=max(bb[i],bb[i-cost]+weight);

}

void ni(int cost,int weight)

{


int i;


for(i=vv;i>=cost;i--)


bb[i]=max(bb[i],bb[i-cost]+weight);

}

int main()

{


char str[5000];


int n,w[5001],v[5001],i,j,amount[5001],v1,w1,k;


while(scanf("%d %d",&n,&vv)!=EOF)


{

memset(amount,0,sizeof(amount));


q=0;


for(i=1;i<=n;i++)


{


scanf("%s %d %d",str,&w1,&v1);


for(j=0;j<q;j++)


if(w1==w[j]&&v1==v[j])


{


amount[j]++;


break;


}


if(j==q)


{


w[q]=w1;v[q]=v1;


amount[q]=1;


q++;


}


}


memset(bb,0,sizeof(bb));


for(i=0;i<q;i++)


{


if(v[i]*amount[i]>=vv)


shun(v[i],w[i]);


else


{


k=1;


while(k<=amount[i])


{


ni(k*v[i],k*w[i]);


amount[i]-=k;


k*=2;


}


ni(amount[i]*v[i],amount[i]*w[i]);


}


}


printf("%d\n",bb[vv]);


}


return 0;

}

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3732