poj 1276 Cash Machine (多重背包)

链接:poj 1276

题意:已知金额cash,给定几种不同面值的货币的数量及面值,求利用给定的货币可以凑成

小于等于cash的金额的最大值

分析:因为每种货币的面值及数量已知,可以将其转化为多重背包,背包的容量即为cash,

每个物品的价值及费用都为每种货币的面值。

多重背包可以转化为01背包,不过这样会超时,为了避免这样,可以转化为完全背包和二进制思想的01背包

#include<stdio.h>
#include<string.h>
int f[100010],v;
int max(int a,int b)
{
    return a>b?a:b;
}
void zeroone(int cost,int weight)  //01背包
{
    int i;
    for(i=v;i>=cost;i--)
        f[i]=max(f[i],f[i-cost]+weight);
}
void complete(int cost,int weight)       //完全背包
{
    int i;
    for(i=cost;i<=v;i++)
        f[i]=max(f[i],f[i-cost]+weight);
}
void multiple(int num,int cost,int weight)      //多重背包
{
    int k;
    if(num*weight>=v){
        complete(cost,weight);
        return ;
    }
    for(k=1;k<num;k*=2){
        zeroone(k*cost,k*weight);
        num-=k;
    }
    zeroone(num*cost,num*weight);
}
int main()
{
    int i,n,num[1010],w[1010];
    while(scanf("%d",&v)!=EOF){
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%d%d",&num[i],&w[i]);
        memset(f,0,sizeof(f));
        for(i=1;i<=n;i++)
            multiple(num[i],w[i],w[i]);
        printf("%d\n",f[v]);
    }
    return 0;
}

poj 1276 Cash Machine (多重背包)

时间: 2024-10-11 18:07:51

poj 1276 Cash Machine (多重背包)的相关文章

POJ 1276 Cash Machine(多重背包的二进制优化)

题目网址:http://poj.org/problem?id=1276 思路: 很明显是多重背包,把总金额看作是背包的容量. 刚开始是想把单个金额当做一个物品,用三层循环来 转换成01背包来做.T了-- 后面学习了 用二进制来处理数据. 简单地介绍一下二进制优化:?(? ? ??)  假设数量是8,则可以把它看成是1,2,4,1的组合,即这4个数的组合包括了1-8的所有取值情况.这是为什么呢?将它们转换成二进制再观察一下: 1:1 2:10 4:100 1:1 二进制都只有0,1.所以1,2,4

POJ 1276 Cash Machine 多重背包--二进制优化

点击打开链接 Cash Machine Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28337   Accepted: 10113 Description A Bank plans to install a machine for cash withdrawal. The machine is able to deliver appropriate @ bills for a requested cash amount

POJ 1276 Cash Machine 背包题解

典型的多重背包的应用题解. 可以使用二进制优化,也可以使用记录当前物品的方法解,速度更加快. const int MAX_CASH = 100001; const int MAX_N = 11; int tbl[MAX_CASH], nums[MAX_N], bills[MAX_N], cash, n; int bag() { if (cash <= 0 || n <= 0) return 0; memset(tbl, 0, sizeof(int) * (cash+1)); for (int

【转载】poj 1276 Cash Machine 【凑钱数的问题】【枚举思路 或者 多重背包解决】

转载地址:http://m.blog.csdn.net/blog/u010489766/9229011 题目链接:http://poj.org/problem?id=1276 题意:机器里面共有n种面额的钱币,每种各ni张,求机器吐出小于等于所要求钱币的最大值 解析1:这题大牛都用了多重背包,不过,我一同学想出了一种就这题而言特别简单有效的方 法.(话说我就认为这题本来就不需要用到背包的,因为n的范围只到10,太小了).方法就是对钱进行遍历,看这些钱一共能组成多少面额的钱,然后从 cash向下枚

poj 1276 Cash Machine(多重背包)

Cash Machine Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26954   Accepted: 9533 题目大意:有各种不同面值的货币,每种面值的货币有不同的数量,请找出利用这些货币可以凑成的最接近且小于等于给定的数字cash的金额. 多重背包转0 1背包 对于第 i 种货币可能的状态为w[ i ]到cash 状态方程 dp[j]=dp[ j-c[i] ]+w[i]   (c[ i ] 表示"体积"

POJ1276:Cash Machine(多重背包)

题目:http://poj.org/problem?id=1276 多重背包模板题,没什么好说的,但是必须利用二进制的思想来求,否则会超时,二进制的思想在之前的博客了有介绍,在这里就不多说了. #include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> #include <math.h> using namespace std; int V,n,w

POJ 1276 Cash Machine 【DP】

多重背包的模型,但一开始直接将N个物品一个一个拆,拆成01背包竟然T了!!好吧OI过后多久没看过背包问题了,翻出背包九讲看下才发现还有二进制优化一说........就是将n个物品拆成系数:1,2,4,8....*物品价值和空间的物品,在这题中只要乘上money[i]就行了,从二进制考虑发现,这样可以组成0~n中所有的数 #include <iostream> #include <cstdio> #include<string.h> using namespace std

POJ 1276 Cash Machine

题意:给你n种面值的钱,告诉你每种面值钱的面值和个数,问能凑出最大的不大于m的钱数是多少. 解法:多重背包.我觉得直接多重背包转01应该会T……又懒得二进制搞……用了POJ1472的思路搞了一下…… 代码: #include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #incl

poj 1276 Cash Machine(dp 水题)

Language: Default Cash Machine Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 27799   Accepted: 9913 Description A Bank plans to install a machine for cash withdrawal. The machine is able to deliver appropriate @ bills for a requested c