标签:
POJ 2392 Space Elevator 多重背包 || 01背包
Description:NULL
然后。。题解先等会的。。先挖个坑把代码填上。。
顺带:{
问题可以转化为可达的最高高度。加上高度很低,空间还是吃的消的。所以直接开一维高度bool存这个高度能不能到达之后dp。
上面方法比这个f[i]表示用前i块积木达成的最高高度优的地方在于,如果用了这个方法,f无法保存哪些已经到达过了,保存的是最高的,还要另开一个数组存历史已经达到的高度。
所以何必多此一举直接用f[i]开布尔就行了。
总之。。做了一些dp题一点点暗搓搓的感受就是。。在写的时候要保证当前状态的上一个状态要可达(或者是当前解依靠的状态)。。而且那个状态就是那个状态还没有被改写。。涉及到了遍历顺序和初始化等等等的问题。。
}
这个由于每个物品的数量范围是1<=x<=10。数据范围太水了可以直接n^3循环变成01背包做。。
但是数据一大就要多重背包了。主要是多重背包的效率比01背包这种高很多
以下是对比图。第一个01背包。第二个多重背包
渣代码:
1 #include <iostream>
2 #include <string.h>
3 #include <math.h>
4 #include <algorithm>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #define ll long long
8
9 using namespace std;
10 bool f[40005];int n;
11 struct qwq{ int h, l, c; } a[405];
12 int cmp(qwq x, qwq y){ return x.l < y.l; }
13 void zeroone(int val, int lim) { for(int i = lim; i >= val; i --) f[i] |= f[i - val]; }
14 void complete(int val, int lim) { for(int i = val; i <= lim; i ++) f[i] |= f[i - val]; }
15 void multi(int high, int lim, int num)
16 {
17 if(high * num >= lim){
18 complete(high, lim); return ;
19 }
20 int tmp = 1;
21 while(num >= tmp){
22 zeroone(tmp * high, lim);
23 num -= tmp;
24 tmp <<= 1;
25 }
26 zeroone(num * high, lim);
27 }
28 int main()
29 {
30 scanf("%d", &n);
31 for(int i = 1; i <= n; i ++){
32 scanf("%d%d%d", &a[i].h, &a[i].l, &a[i].c);
33 }
34 sort(a + 1, a + n + 1, cmp);
35 memset(f, 0, sizeof(f));
36 f[0] = 1;
37 for(int i = 1; i <= n; i ++){
38 multi(a[i].h, a[i].l, a[i].c);
39 }
40 for(int i = a[n].l; i >= 0; i --){
41 if(f[i]) {
42 printf("%d\n", i); return 0;
43 }
44 }
45 return 0;
46 }
1 #include <iostream>
2 #include <string.h>
3 #include <math.h>
4 #include <algorithm>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #define ll long long
8
9 using namespace std;
10 bool f[40005];int n;
11 struct qwq{ int h, l, c; } a[405];
12 int cmp(qwq x, qwq y){ return x.l < y.l; }
13
14 int main()
15 {
16 scanf("%d", &n);
17 for(int i = 1; i <= n; i ++){
18 scanf("%d%d%d", &a[i].h, &a[i].l, &a[i].c);
19 }
20 sort(a + 1, a + n + 1, cmp);
21 memset(f, 0, sizeof(f));
22 f[0] = 1;
23 int cur = 0;
24 for(int i = 1; i <= n; i ++){
25 for(int j = cur; j >= 0; j --){
26 if(!f[j]) continue;
27 for(int k = 1; k <= a[i].c; k ++){
28 int tmp = k * a[i].h + j;
29 if(tmp > a[i].l) break;
30 f[tmp] = 1;
31 cur = max(cur, tmp);
32 }
33 }
34 }
35 for(int i = a[n].l; i >= 0; i --){
36 if(f[i]) {
37 printf("%d\n", i); return 0;
38 }
39 }
40 return 0;
41 }
NAILED IT..
---------------------------
标签:
原文地址:http://www.cnblogs.com/shadyqwq-juruo/p/5720828.html