poj1276(DP多重背包)

来源:互联网 发布:手机怎样看淘宝的积分 编辑:程序博客网 时间:2024/05/01 13:07

http://poj.org/problem?id=1276

Cash Machine
Time Limit: 1000MSMemory Limit: 10000KTotal Submissions: 18966Accepted: 6599

Description

A Bank plans to install amachine for cash withdrawal. The machine is able to deliverappropriate @ bills for a requested cash amount. The machine usesexactly N distinct bill denominations, say Dk, k=1,N, and for eachdenomination Dk the machine has a supply of nk bills. Forexample,

N=3, n1=10, D1=100, n2=4, D2=50, n3=5, D3=10

means the machine has a supply of 10 bills of @100 each, 4 bills of@50 each, and 5 bills of @10 each.

Call cash the requested amount of cash the machine should deliverand write a program that computes the maximum amount of cash lessthan or equal to cash that can be effectively delivered accordingto the available bill supply of the machine.

Notes:
@ is the symbol of the currency delivered by the machine. Forinstance, @ may stand for dollar, euro, pound etc.

Input

The program input is fromstandard input. Each data set in the input stands for a particulartransaction and has the format:

cash N n1 D1 n2 D2 ... nN DN

where 0 <= cash <= 100000 is theamount of cash requested, 0 <=N <= 10is the number of bill denominations and 0 <= nk<= 1000 is the number of available bills for the Dkdenomination, 1 <= Dk <= 1000, k=1,N.White spaces can occur freely between the numbers in the input. Theinput data are correct.

Output

For each set of data the programprints the result to the standard output on a separate line asshown in the examples below.

Sample Input

735 3  4 125  6 5  3 350633 4  500 30  6 100  1 5  0 1735 00 3  10 100  10 50  10 10

Sample Output

73563000

Hint

The first data set designates atransaction where the amount of cash requested is @735. The machinecontains 3 bill denominations: 4 bills of @125, 6 bills of @5, and3 bills of @350. The machine can deliver the exact amount ofrequested cash.

In the second case the bill supply of the machine does not fit theexact amount of cash requested. The maximum cash that can bedelivered is @630. Notice that there can be several possibilitiesto combine the bills in the machine for matching the deliveredcash.

In the third case the machine is empty and no cash is delivered. Inthe fourth case the amount of cash requested is @0 and, therefore,the machine delivers no cash.

Source

Southeastern Europe 2002
 
直接上代码就是简单的多重背包,直接套模板
#include<stdio.h>
#include<string.h>
intf[1000010],weight[1010],cost[1010];
int n,v;
int max(intx,int y)
{
       returnx>y?x:y;
}
void zero(intcost,int weight)
{
       int j;
       //for(i=1;i<=n;i++)
               for(j=v;j>=cost;j--)
                       f[j]=max(f[j],f[j-cost]+weight);
}
void comple(intcost,int weight)
{
       int j;
       //for(i=1;i<=n;i++)
               for(j=cost;j<=v;j++)
                       f[j]=max(f[j],f[j-cost]+weight);
}
void multi(intcost,intweight,int amount)
{
       if(cost*amount>=v)
       {
               comple(cost,weight);
               return;
       }
       else
       {
               int k=1;
               while(k<amount)
               {
                       zero(k*cost,k*weight);
                       amount-=k;
                       k*=2;
               }
       }
       zero(amount*cost,amount*weight);
}
int main()
{
       while(scanf("%d%d",&v,&n)!=EOF)
       {
               int i;
               for(i=1;i<=n;i++)
                       scanf("%d%d",&cost[i],&weight[i]);
               memset(f,0,sizeof(f));
               for(i=1;i<=n;i++)
                       multi(weight[i],weight[i],cost[i]);
               printf("%d\n",f[v]);
       }
       return 0;
}

 
2012.8.6
不知道为什么错了测试数据都是问题居然还出现tle和re神奇
#include<iostream>
#include<cstring>
#define MAXN 1010
int f[1000010],c[MAXN],w[MAXN];
int m,n;
int max(int a,int b)
{
 return a>b?a:b;
}
void ZeroOnePack(int cost,int weight)
{
 for(int v=m;v>=cost;v--)
  f[v]=max(f[v],f[v-cost]+weight);
}
void CompletePack(int cost,int weight)
{
 for(int v=cost;v<=m;v++)
  f[v]=max(f[v],f[v-cost]+weight);
}
void MultiplePack(int cost,intweight,int amount)
{
 if(cost*amount>=m)
 {
  CompletePack(cost,weight);
  return;
 }
 else
 {
  int k=1;
  while(k<amount)
  {
   ZeroOnePack(k*cost,k*weight);
   amount-=k;
   k*=2;
  }
 }
 ZeroOnePack(amount*cost,amount*weight);
}
int main()
{
 int m,n;
 while(scanf("%d",&m)!=EOF)
 {
  int i;
  scanf("d",&n);
  for(i=1;i<=n;i++)
   scanf("%d%d",&c[i],&w[i]);
  memset(f,0,sizeof(f));
  for(i=1;i<=n;i++)
  {
   MultiplePack(w[i],w[i],c[i]);
  }
  printf("%d\n",f[m]);
 }
 return 0;
}
 
 
原创粉丝点击