HDU2191 多重背包 三种解法
来源:互联网 发布:天音网络黄涛 编辑:程序博客网 时间:2024/04/28 07:09
Problem Address:http://acm.hdu.edu.cn/showproblem.php?pid=2191
【思路】
简单的多重背包。
但是多重背包并不简单。以下简单介绍多重背包的三种解法。
第一种:O(V*Σ(Ki))
这就是最平常的解法。把多重背包当做01背包来做。
把每一件物品的k个数量拆分为k个物品,然后进行01背包。
第二种:O(V*∑([log2Ki]))
这是前一个方法的升级。利用了二进制的思想。
把k拆分为1、2、4……2^(t-1)、Ki-2^t+1的数列,其中t是满足Ki-2^t+1>0的最大整数。
可以想象一下,比如7以内的任意数,是可以通过1、2、4这三个数组合而来。
以上两种方法在《背包九讲》中都有讲解。
第三种:O(VN)
这种方法利用了单调队列。可以先了解单调队列。
详细方法参考国家集训队论文《浅谈几类背包问题》。
达到了和01背包一样的时间复杂度。
【代码】
第一种:O(V*Σ(Ki))
#include <iostream>using namespace std;const int maxn = 100;int dp[maxn+5];int main(){int t;int n, m, p, h, c;int i, j, k;scanf("%d", &t);while(t--){memset(dp, 0, sizeof(dp));scanf("%d %d", &n, &m);for (i=0; i<m; i++){scanf("%d %d %d", &p, &h, &c);for (j=n; j>=0; j--){for (k=1; k<=c && j+k*p<=n; k++){if (dp[j]+k*h>dp[j+k*p])dp[j+k*p] = dp[j] + k*h;}}}printf("%d\n", dp[n]);}return 0;}
第二种:O(V*∑([log2Ki]))
#include <iostream>using namespace std;const int maxn = 100;int dp[maxn+5];int main(){int t;int n, m, p, h, c;int i, j, k, w, val;scanf("%d", &t);while(t--){memset(dp, 0, sizeof(dp));scanf("%d %d", &n, &m);for (i=0; i<m; i++){scanf("%d %d %d", &p, &h, &c);for (k=1; c-k*2+1>0; k*=2){w = k*p;val = k*h;for (j=n-w; j>=0; j--){if (dp[j]+val>dp[j+w])dp[j+w] = dp[j]+val;}}k = c - k + 1;w = k*p;val = k*h;for (j=n-w; j>=0; j--){if (dp[j]+val>dp[j+w])dp[j+w] = dp[j]+val;}}printf("%d\n", dp[n]);}return 0;}
第三种:O(VN)
#include <iostream>using namespace std;const int maxn = 100;int dp[maxn+5];int A[maxn+5];int B[maxn+5];int L, R;inline void insert(int a, int b)//插入一个position为a,值为b的元素到队列中{while(R>=L && b>B[R]) R--;R++;A[R] = a;B[R] = b;}int main(){int t;int n, m, p, h, c;int i, j;int d;scanf("%d", &t);while(t--){memset(dp, 0, sizeof(dp));scanf("%d %d", &n, &m);for (i=0; i<m; i++){scanf("%d %d %d", &p, &h, &c);for (d=0; d<p; d++){L = 1;R = 0;for (j=0; j<=(n-d)/p; j++){insert(j, dp[j*p+d]-j*h);if (A[L]<j-c)//如果队列的首元素已经失效L++;dp[j*p+d] = B[L] + j*h;}}}printf("%d\n", dp[n]);}return 0;}
- HDU2191 多重背包 三种解法
- hdu2191(多重背包)
- hdu2191(多重背包)
- hdu2191多重背包
- HDU2191多重背包问题
- hdu2191(多重背包)
- HDU2191多重背包
- hdu2191 多重背包
- hdu2191(多重背包)
- hdu2191 多重背包问题
- DP--多重背包--HDU2191
- HDU2191 多重背包
- HDU2191(多重背包)
- HDU2191(多重背包)
- 多重背包(HDU2191)
- 二维-hdu2191-多重背包
- 多重背包 HDU2191
- hdu2191 多重背包
- Lucene索引和搜索核心类的简单介绍
- HR说事:谈谈面试礼仪 (转自网易官方校园招聘网站)
- Ioc容器Autofac介绍
- sgu 326
- Socket iocp
- HDU2191 多重背包 三种解法
- c++ const 成员函数
- Mr. Process的一生-Linux内核的社会视角 (1)调度
- Uboot启动流程
- 自定义Ant Task
- 正弦函数及其FFT变换(一)
- HDU--3884[Hinanai Tenshi’s peach garden] 枚举汇聚点O(N^2)
- 某EDN博客是俺好多工作过程总结---该网站改版后竟然没了!
- 最小生成树