POJ1267 Cash machine 多重背包

来源:互联网 发布:ubuntu vi命令 编辑:程序博客网 时间:2024/05/29 15:40

传送门:POJ1276

题意:给定一种新货币的多种面额和每种面额的数量和一个数额上限,问在不超过数额上限的前提下用给定的货币最多能凑出多大数额来。

思路:典型的多重背包,可以说是模板题,只不过本题中w[i]==v[i]而已。

可以用二进制优化,也可以单调队列优化。

不明白多重背包是啥的请自行搜索《背包九讲》。

二进制优化代码:

#include<stdio.h>#include<iostream>#include<string.h>#include<math.h>#include<algorithm>#include<queue>#include<stack>#include<set>#include<vector>#include<map>#define ll long long#define pi acos(-1)#define inf 0x3f3f3f3fusing namespace std;typedef pair<int,int>P;int num[15],w[15],v[15];int dp[100010];int V,n;void zero(int cost,int weight){for(int i=V;i>=cost;i--)dp[i]=max(dp[i],dp[i-cost]+weight);}void complet(int cost,int weight){for(int i=cost;i<=V;i++)dp[i]=max(dp[i],dp[i-cost]+weight);}void multi(int cost ,int amount ,int weight){   if(cost*amount>=V)   {   complet(cost,weight);   return;   }   int k=1;   while(k<amount)   {   zero(k*cost,k*weight);   amount-=k;   k=k*2;   }   zero(amount*cost,amount*weight);}//多重背包的二进制优化int main(){while(~scanf("%d%d",&V,&n)){memset(dp,0,sizeof(dp));for(int i=1;i<=n;i++)scanf("%d%d",&num[i],&w[i]),v[i]=w[i];for(int i=1;i<=n;i++){multi(w[i],num[i],v[i]);}printf("%d\n",dp[V]);}    return 0;}

单调队列优化(竟然还比上一种慢):

#include<stdio.h>#include<string.h>int w[15],c[15],v[15],dp[100010],V,n;struct Queue{    int num,value;}que[250005];int head,tail;void enqueue (int x,int y){    while (head<=tail && que[tail].value<y) tail--;    que[++tail].num=x;que[tail].value=y;}void multipack(){    int i,j,d;    memset(dp,0,sizeof(dp));for (i=1 ; i<=n ; ++i){        if (c[i] > V/w[i]) c[i]=V/w[i];        for (d=0 ; d<w[i] ; ++d)        {            head=1;tail=0;            for (j=0 ; j<=(V-d)/w[i] ; ++j)            {                enqueue(j , dp[j*w[i]+d]-j*v[i]);                while (que[head].num<j-c[i] && head<=tail) head++;                dp[j*w[i]+d]=que[head].value+j*v[i];            }        }    }}int main(){while(~scanf("%d%d",&V,&n)){for(int i=1;i<=n;i++)scanf("%d%d",&c[i],&w[i]),v[i]=w[i];multipack();printf("%d\n",dp[V]);}    return 0;}


1 0
原创粉丝点击