HDU 2844&& POJ 1742
来源:互联网 发布:淘宝买电脑可靠吗 编辑:程序博客网 时间:2024/05/17 21:56
Whuacmers use coins.They have coins of value A1,A2,A3…An Silverland dollar. One day Hibix opened purse 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
多重背包问题:
题目求的是m以内的组合数
算出具体值(HDU能过但是POJ会超时):
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;#define maxn 100050#define INF 0x3f3f3f3fint dp[maxn], a[maxn], c[maxn];int main(){ int n, m, i, j, k, ans; while(~scanf("%d %d",&n, &m) && (n!=0||m!=0)){ memset(dp, -INF,sizeof(dp)); memset(a, 0,sizeof(a)); memset(c, 0,sizeof(c)); for(i = 1; i <= n; ++i){ scanf("%d", &a[i]); } for(j = 1; j <= n; ++j){ scanf("%d", &c[j]); } dp[0] = 1; for(i = 1; i <= n; ++i){ if(a[i] * c[i] >= m){ for(j = a[i]; j <= m; ++j){ dp[j] = max(dp[j], dp[j-a[i]] + a[i]); } } else{ for(k = 1; k <= c[i]; k *= 2){ for(j = m; j >= a[i] * k; --j){ dp[j] = max(dp[j], dp[j-a[i]*k]+a[i]*k); } c[i] -= k; } if(c[i] > 0){ for(j = m; j >= a[i] * c[i]; --j){ dp[j] = max(dp[j], dp[j-a[i]*c[i]]+a[i]*c[i]); } } } } ans = 0; for(j = 1; j <= m; ++j){ if(dp[j] >= 0){ ans++; } } printf("%d\n", ans); }}
因为题目要求的只是m以内的组合数,dp[i][j]记录前i种硬币价值为j是否有组合,num[i][j]记录硬币i在价值为j时的数量,优化空间用滚动数组。
TLE问题解决!(这种做法一般只适用于限制条件与所求值是对应的,一般的多重背包问题重量是限制条件,要求的是最大价值,这一题限制条件是金钱,要求的也是金钱。转移状态方程长得像这个样子的→_→dp[j] = max(dp[j], dp[j-a[i]] + a[i]);)
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;#define maxn 100050#define INF 0x3f3f3f3fint dp[maxn], num[maxn], a[maxn], c[maxn];int main(){ int n, m, i, j, k, ans; while(~scanf("%d %d",&n, &m) && (n!=0||m!=0)){ memset(dp, 0,sizeof(dp)); for(i = 1; i <= n; ++i){ scanf("%d", &a[i]); } for(j = 1; j <= n; ++j){ scanf("%d", &c[j]); } dp[0] = 1; ans = 0; for(i = 1; i <= n; ++i){ memset(num, 0, sizeof(num)); for(j = a[i]; j <= m; ++j){ if(!dp[j] && c[i] > num[j - a[i]]&&dp[j-a[i]]){ num[j] = num[j-a[i]] + 1; dp[j] = 1; ++ans; } } } printf("%d\n", ans); }}
- HDU 2844&& POJ 1742
- HDU 2844/POJ 1742 Coins
- poj 1742 && hdu 2844 Coins
- Coins (poj 1742 && hdu 2844 DP)
- Hdu 2844 & Poj 1742 结题报告
- POJ 1742 && HDU 2844 Coins(多重背包问题)
- poj 1014 ,hdu 2844 (多重背包)
- poj hdu Tunnel Warfare
- hdu 1700 poj 2954
- poj 1177 && hdu 1828
- poj 3990 hdu 3694
- POJ 1466/HDU 1068
- hdu,poj 分类
- POJ 2238 && HDU 4294
- hdu 4009 && POJ 3164
- HDU 1043、POJ 1077
- 刷poj、hdu有感
- hdu 1540 && poj 2892
- 全文检索技术 solr(三)solr安装、启动
- 生产者消费者模式
- (65)LinkLIst练习:运用LinkList方法模拟堆栈、队列
- RB_TREE 红黑树插入及删除
- angular2-使用bootstrap-select插件
- HDU 2844&& POJ 1742
- 【剑指offer】面试题 30:包含 min 函数的栈
- 线程间通信
- 华为机试:二维数组操作、公共字串计算
- 考研英语笔记——时文长难句一
- 多线程之线程局部变量ThreadLocal及原理
- C_栈和队列(ADT)-栈的表示和实现
- 刷机介绍----超详细
- 解决SpringMVC接收前台上传文件为null