Coins
Time Limit: 3000MS   Memory Limit: 30000K
Total Submissions: 32309   Accepted: 10986

Description

People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box and found there were some coins.He decided to buy a very nice watch in a nearby shop. He wanted to pay the exact price(without change) and he known the price would not more than m.But he didn't know the exact price of the watch. 
You are to write a program which reads n,m,A1,A2,A3...An and C1,C2,C3...Cn corresponding to the number of Tony's coins of value A1,A2,A3...An then calculate how many prices(form 1 to m) Tony can pay use these coins. 

Input

The input contains several test cases. The first line of each test case contains two integers n(1<=n<=100),m(m<=100000).The second line contains 2n integers, denoting A1,A2,A3...An,C1,C2,C3...Cn (1<=Ai<=100000,1<=Ci<=1000). The last test case is followed by two zeros.

Output

For each test case output the answer on a single line.

Sample Input

3 10
1 2 4 2 1 1
2 5
1 4 2 1
0 0

Sample Output

8
4 题意:给出3种硬币的面额和数量,能拼成不大于m的多少种;
多重背包可解,因为只要求行或不行就可以了,所以就两种状态在01和完全背包的时候没必要求可行解,只要确定行或不行就ok了,所以直接与dp[j - a[i]] 或运算,
注意的是,位运算真的好快,把dp设成int,用关系运算||,是超时的,改成位运算的|直接3000ms卡过;
改成bool型直接2204ms;
 #include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAX = + ;
bool dp[MAX];
int a[ + ],c[ + ];
int n,m;
void ZeroOnePage(int cost)
{
for(int i = m; i >= cost; i--)
{
dp[i] |= dp[i - cost];
}
}
void CompletePage(int cost, int mount)
{
for(int i = cost; i <= m; i++)
dp[i] |= dp[i - cost];
}
void MultiplePage(int cost, int mount)
{
if(cost * mount >= m)
{
CompletePage(cost, mount);
return ;
}
int k = ;
while(k < mount)
{
ZeroOnePage(k * cost);
mount -= k;
k <<= ;
}
if(mount > )
ZeroOnePage(mount * cost);
return ;
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
if(n == && m == )
break;
for(int i = ; i <= n; i++)
scanf("%d", &a[i]);
for(int i = ; i <= n; i++)
scanf("%d", &c[i]);
memset(dp, , sizeof(dp));
dp[] = ;
for(int i = ; i <= n; i++)
if(c[i])
MultiplePage(a[i], c[i]);
int sum = ;
for(int i = ; i <= m; i++)
if(dp[i])
sum++;
printf("%d\n",sum);
} return ;
}

多重背包好理解

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAX = + ;
bool dp[MAX];
int a[ + ],c[ + ];
int n,m;
void ZeroOnePage(int cost)
{
for(int i = m; i >= cost; i--)
{
dp[i] |= dp[i - cost];
}
}
void CompletePage(int cost, int mount)
{
for(int i = cost; i <= m; i++)
dp[i] |= dp[i - cost];
}
void MultiplePage(int cost, int mount)
{
if(cost * mount >= m)
{
CompletePage(cost, mount);
return ;
}
int k = ;
while(k < mount)
{
ZeroOnePage(k * cost);
mount -= k;
k <<= ;
}
//这里是还剩下的mount
if(mount > )
ZeroOnePage(mount * cost);
return ;
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
if(n == && m == )
break;
for(int i = ; i <= n; i++)
scanf("%d", &a[i]);
for(int i = ; i <= n; i++)
scanf("%d", &c[i]);
memset(dp, , sizeof(dp));
dp[] = ;
for(int i = ; i <= n; i++)
if(c[i])
MultiplePage(a[i], c[i]);
int sum = ;
for(int i = ; i <= m; i++)
if(dp[i])
sum++;
printf("%d\n",sum);
} return ;
} 多重背包好理解
这种解法看不懂
 #include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAX = + ;
int dp[MAX],used[MAX],a[ + ],c[ + ];
int n,m;
int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
if(n == && m == )
break;
for(int i = ; i <= n; i++)
scanf("%d", &a[i]);
for(int i = ; i <= n; i++)
scanf("%d", &c[i]);
memset(dp, , sizeof(dp));
dp[] = ;
int sum = ;
for(int i = ; i <= n; i++)
{
memset(used, , sizeof(used));
for(int j = a[i]; j <= m; j++)
{
if(dp[j] == && dp[j - a[i]] && used[j - a[i]] < c[i])
{
sum++;
dp[j] = ;
used[j] = used[j - a[i]] + ;
}
}
}
printf("%d\n",sum);
} return ;
}

POJ1742Coins(多重背包)的更多相关文章

  1. 洛谷P1782 旅行商的背包[多重背包]

    题目描述 小S坚信任何问题都可以在多项式时间内解决,于是他准备亲自去当一回旅行商.在出发之前,他购进了一些物品.这些物品共有n种,第i种体积为Vi,价值为Wi,共有Di件.他的背包体积是C.怎样装才能 ...

  2. HDU 2082 找单词 (多重背包)

    题意:假设有x1个字母A, x2个字母B,..... x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,..... 字母Z的价值为26.那么,对于给定的字母,可以找到多少价值<=50的 ...

  3. Poj 1276 Cash Machine 多重背包

    Cash Machine Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26172   Accepted: 9238 Des ...

  4. poj 1276 Cash Machine(多重背包)

    Cash Machine Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 33444   Accepted: 12106 De ...

  5. (混合背包 多重背包+完全背包)The Fewest Coins (poj 3260)

    http://poj.org/problem?id=3260   Description Farmer John has gone to town to buy some farm supplies. ...

  6. (多重背包+记录路径)Charlie's Change (poj 1787)

    http://poj.org/problem?id=1787   描述 Charlie is a driver of Advanced Cargo Movement, Ltd. Charlie dri ...

  7. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  8. POJ1742 Coins[多重背包可行性]

    Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 34814   Accepted: 11828 Descripti ...

  9. POJ1276Cash Machine[多重背包可行性]

    Cash Machine Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 32971   Accepted: 11950 De ...

随机推荐

  1. javac编译提示错误需要为 class、interface 或 enum

    HelloWorld.java:1: 需要为 class.interface 或 enum锘缝ublic class HelloWorld{^1 错误 这个错误出现的原因主要是在中文操作系统中,使用一 ...

  2. [MS] 微软官网下载安装SQLSERVER2019的rpm

    快速入门:安装 SQL Server 和 Red Hat 上创建数据库 https://docs.microsoft.com/zh-cn/sql/linux/quickstart-install-co ...

  3. lamp下mysql安全加固

    lamp下mysql安全加固 1.修改root用户口令,删除空口令 缺省安装的MySQL的root用户是空密码的,为了安全起见,必须修改为强密码,所谓的强密码,至少8位,由字母.数字和符号组成的不规律 ...

  4. Java占位符

    一.背景 在使用java开发的过程中,经常需要使用将字符串拼接到一起(比如,用于日志输出),常用方法如下: 使用+将不同字符串进行拼接 使用StringBuilder 使用String.format ...

  5. 给kali linux2.0装一个中文输入法

    没有中文输入法好痛苦啊.. 毕竟做了无限网卡,虚拟机和主机可以完完全全当两台设备使用了,所以kali还是需要一个中文输入法才方便. 由于使用的是比较新的kali版本和源,现在安装fcitx已经可以直接 ...

  6. BZOJ2002[Hnoi2010]弹飞绵羊——LCT

    题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系 ...

  7. openfalcon架构及相关服务配置详解

    一:openfalcon组件 1.falcon-agent 数据采集组件 agent内置了一个http接口,会自动采集预先定义的各种采集项,每隔60秒,push到transfer. 2.transfe ...

  8. bzoj 3289 : Mato的文件管理 (莫队+树状数组)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3289 思路: 求区间最小交换的次数将区间变成一个不降序列其实就是求区间逆序对的数量,这 ...

  9. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) A,B,C

    A.题目链接:http://codeforces.com/contest/828/problem/A 解题思路: 直接暴力模拟 #include<bits/stdc++.h> using ...

  10. MT【63】证明不是周期函数

    证明$f(x)=sinx^2$不是周期函数. 反证:假设是周期函数,周期为$T,T>0$. $$f(0)=f(T)\Rightarrow sinT^2=0\Rightarrow T^2=k_1\ ...