POJ 1742 Coins 多重背包(单调队列优化)
来源:互联网 发布:各国网络制式 编辑:程序博客网 时间:2024/05/22 10:42
题意:给定n,m,表示有n种硬币,接下来给定两个数组A[i],C[i]分别表示第i种硬币的面值以及个数,问用这些硬币可以凑出多少[1,m]范围内的数额。输入以n,m都为0结束。
首先可以转换为背包模型,f[i][j]表示前i种硬币是否可以凑出数额j,利用滚动数组可以优化第一维。
对于一个多重背包的模型,可以很容易地写出来这道题的转移方程:f[j] = max(f[j-k*A[i]]),0<=k<=C[i]
写完整是f[i][j] = max(f[i-1][j-k*A[i]]),可以看出来,对于一个状态f[i][j],它的决策是固定的一些状态f[i-1][j-k*A[i]],那么我们可以通过单调队列优化,把这些状态放到单调队列中,来做到O(1)决策。
为了做到这个,会稍微改变一下f[i]这一维中的m个状态的求解顺序:正常情况下,写的循环是
for (int i = 1; i <= n; i++) for (int k = 0; k <= C[i]; k++) for (int j = m; j-k*A[i] >= 0; j--) f[i][j] = max (f[i][j], f[i-1][j-k*A[i]);
f[i]是按顺序求出来的。
而使用单调队列优化后,就变成了模A[i]意义下的每个同余类的顺序球出来。
for (int i = 1; i <= n; i++)for (int mod = 0; mod < A[i]; mod++){ q = h = 0; for (int j = mod; j <= m; j+=A[i]) { /*……*/ }}
这道题的单调队列很好写(方程那么简单都明摆着了)。
可以加个优化,当C[i] == 1时用普通背包策略,A[i]*C[i] >= m时用完全背包的策略。
#include <cstdio>#include <cstring>#include <algorithm>#define MX 100005using namespace std;int n, m, h, t, A[1005], C[1005];bool f[MX], q[MX];int main (){ while (~scanf ("%d %d", &n, &m) && n+m) { for (int i = 1; i <= n; i++) scanf ("%d", A+i); for (int i = 1; i <= n; i++) scanf ("%d", C+i); memset (f, 0, sizeof f); int ans = 0; f[0] = 1; for (int i = 1; i <= n; i++) { if (C[i] == 1) { for (int j = m; j >= A[i]; j--) if (!f[j] && f[j-A[i]]) f[j] = 1, ans++; } else if (A[i] * C[i] > m) { for (int j = A[i]; j <= m; j++) if (!f[j] && f[j-A[i]]) f[j] = 1, ans++; } else { for (int mod = 0; mod < A[i]; mod++) { int sum = 0; h = t = q[0] = 0; for (int j = mod; j <= m; j+=A[i]) { if (t-h == C[i]+1) sum -= q[++h]; sum += (q[++t] = f[j]); if (!f[j] && sum) f[j] = 1, ans++; } } } } printf ("%d\n", ans); } return 0;}
0 0
- POJ 1742 Coins 多重背包(单调队列优化)
- POJ 1742 Coins 多重背包用单调队列优化
- poj 1742 Coins 单调队列优化多重背包
- POJ 1742 Coins( 单调队列优化多重背包)
- POJ 1742 Coins 单调队列多重背包
- POJ 1742:Coins——单调队列优化的多重背包
- POJ 1742 Coins——不要套单调队列优化多重背包的模板
- poj-1742 Coins(多重背包优化)
- poj 1742 多重背包(单调队列)
- poj 1742 Coins dp 多重背包 优化
- 多重背包(单调队列优化)
- 多重背包(单调队列优化)
- hdu1171 (单调队列优化多重背包)
- 单调队列优化多重背包(含构造问题<POJ 1742 coin>)
- poj 1742coins(优化的多重背包)
- poj 1276 多重背包+二进制优化+单调队列优化
- 多重背包单调队列优化
- 单调队列优化多重背包
- 支持向量机
- Java 接口(interface)和抽象类(abstract class)区别
- NoC路由器架构
- 2015款Mac笔记本安装Windows10系统到外置移动硬盘教程
- 用递归遍历一个目录下的所有文件
- POJ 1742 Coins 多重背包(单调队列优化)
- 杭电5656 CA Loves GCD
- ios 如何单独排序只含有date的数组
- 虫孔Router
- hdoj Rectangles 2056 (数学几何&技巧)求两矩形相交面积
- FZU 2216 The Longest Straight (二分)
- myeclipse在线注册码
- Noc拓扑
- Flask学习笔记(一)