算法:poj 2392 Space Elevator(dp 排序+多重背包)

题目大意:

有n种砖头,每种砖头的高为h,数量为c, 且它放的最高位置不能超过a。 问这些砖 最高能够叠多高?

思路:

先把所有种类砖头按照a从大到小排序,然后直接套多重背包即可 。

代码:

#include<iostream>
#include<queue>
#include<stack>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<string>
#define MP make_pair
#define SQ(x) ((x)*(x))
#define MAX(x, y) ((x)>(y))?(x):(y)
typedef int int64;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
using namespace std;  

const int MAXN = 33;  

int n, m;  

struct Node{
    int h, a, c;
    bool operator<(const Node& rhs)const {
        return a < rhs.a;
    }
}arr[410];  

inline void ZeroOnePack(int* f, int V, int c, int w){
    for(int i=V; i>=c; --i)
        f[i] = max(f[i], f[i-c]+w);
}
inline void CompletePack(int* f, int V, int c, int w){
    for(int i=c; i<=V; ++i)
        f[i] = max(f[i], f[i-c]+w);
}
inline void MultiplePack(int* f, int V, int c, int w, int m){
    if(c*m >= V){
        CompletePack(f, V, c, w);
        return ;
    }
    int k = 1;
    while(k < m){
        ZeroOnePack(f, V, k*c, k*w);
        m -= k;
        k <<= 1;
    }
    ZeroOnePack(f, V, m*c, m*w);
}  

int f[100010];  

int main(){  

    scanf("%d", &n);
    int maxx = 0;
    for(int i=1; i<=n; ++i){
        scanf("%d%d%d", &arr[i].h,&arr[i].a,&arr[i].c);
        maxx = max(maxx, arr[i].a);
    }  

    sort(arr+1, arr+1+n);  

    for(int i=0; i<=maxx; ++i)
        f[i] = 0;  

    for(int i=1; i<=n; ++i)
        MultiplePack(f, arr[i].a, arr[i].h, arr[i].h, arr[i].c);  

    int ans = 0;
    for(int i=0; i<=maxx; ++i)
        ans = max(ans, f[i]);
    printf("%d\n", ans);
    return 0;
}

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索int
, include
, 背包问题
, const
, define
, c 回溯 背包
, w y f
, elevation
, 多重
背包
space elevator、背包dp、dp背包问题、lu2392撸尔山永久地址、2392 39 4,以便于您获取更多的相关知识。

时间: 2024-09-16 04:13:05

算法:poj 2392 Space Elevator(dp 排序+多重背包)的相关文章

算法:POJ 2184 Cow Exhibition (dp 转换01背包)

题目大意: 有N个物品,每个物品有属性Si和Fi,-1000 <= Si, Fi <= 1000, 每种物品最 多只能选一次,问怎样选使得物品的所有Si和Fi属性之和最大,并且要求Si之和与Fi之和都不能下于 0. 思路: 这题想了很久都没思路,于是跟前辈请教了下,恍然大悟.把属性Si当做是物品的 费用,Fi当做是价值,然后做01背包即可. 代码: #include<iostream> #include<queue> #include<stack> #inc

算法:poj 1948 Triangular Pastures (dp 二维01背包)

题目大意: 给N条边,把这些边组成一个三角形,问面积最大是多少?必须把所有边都用上. 思路: 对于已知周长的三角形,我们只要知道两条边的长度变可推出第三条边,所以可以得 到状态方程: f[i][j][k] 表示用前i条边,能否组成长度为j和k的两条边 初始化f[0][0][0] = true: f[i][j][k] = f[i-1][j-len[i]][k] || f[i-1][j][k-len[i]]; 如果f[i][j][k]=true ,那么就计算以j,k,sum-j-k为三条边能否组成三

算法:poj 1837 Balance (dp 01背包)

题目大意: 有一个天平,天平左右两边的手臂长度都是15,手臂上面有些位置会有挂钩.还有G 个砝码 (1 <= G <= 20),它们重量各不相同,在1~25中取值. 给出C个挂钩,它们的位置在 [-15..15],不会重叠.负号的代表在左边臂,正号的在右边. 要求把所有砝码都放在挂钩上,多 个砝码可以挂在同一个挂钩上,问有多少种不同的方案使天平能够平衡? 思路: 天平左臂 的力矩和是负数,右边的力矩和是正数,那么左边+右边的力矩之和,如果是正数,代表天平平衡倾向右边 ,负数代表倾向左边,为0的

POJ 2385 Apple Catching (DP)

Description It is a little known fact that cows love apples. Farmer John has two apple trees (which are conveniently numbered 1 and 2) in his field, each full of apples. Bessie cannot reach the apples when they are on the tree, so she must wait for t

算法:HDU 4681 String (dp, LCS | 多校8)

题意 给出3个字符串A,B,C,要你找一个字符串D, 要满足下面规定 a) D是A的子序列 b) D是B 的子序列 c) C是D的子串 求D的最大长度 要注意子序列和子串的区别,子序列是不连续的,字串是连 续的 思路 由题目可知,C一定是A和B的子序列,那么先假设C在A和B中只有一个子序列,看下 面例子: abcdefdeg acebdfgh cf 可以看到"cf"在A串的[3, 6]区间 内, 在B串的[2,6]区间(黄色背景) 因为所求的C是D的子串,所以在该黄色区间内的其他字母一

[算法问题]合并两个已经排序的数组为另一个数组

问题描述: 设子数组a[0:k]和a[k+1:n-1]已排好序(0<=k<=n-1).试设计一个合并这两个子数组为排好序的数组a[0:n-1]的算法.要求算法在最坏的情况下所用的计算时间为O(n), 且只用到O(1)的辅助空间. 这一题比较简单,看代码就知道了. #include <stdio.h> void DisplayArray(int *pArray, int nLen) { for (int i = 0; i < nLen; ++i) { printf("

算法:uva 672 Gangsters( dp )

题目大意: 有个酒店的门会改变尺寸,变化范围是[0,k],这个门每秒钟尺寸可以变大1,可以 减小1,也可以不变. 现在有n个人,他们的尺寸为si,每个人在ti时刻想要进入酒店,只有在ti时刻 酒店门的尺寸恰好和这个人的尺寸大小相等,这个人才可以进入. 每个人有一个值Pi,当某人进入酒 店,酒店就会增加Pi值. 在[0,T]这段时间内(0秒时酒店的门尺寸状态是0),求让一些人进入酒店 ,使得总Pi值最大. 思路: 开始时,以为同一时间两个人不能同时进入,结果WA了很久. 其 实如果是同一时间,两个

算法:hdu 1011 Starship Troopers (树形背包dp)

题意 有n个洞穴编号为1-n,洞穴间有通道,形成了一个n-1条边的树, 洞穴的入口即根节点是1. 每个洞穴有x只bugs,并有价值y的金子,全部消灭完一个洞穴的虫子,就可以获得这个洞穴的y个金子. 现 在要派m个战士去找金子,从入口进入.每次只有消灭完当前洞穴的所有虫子,才可以选择进入下一个洞穴. 一个战士可以消灭20只虫子,如果要杀死x只虫子,那么要x/20向上取整即(x+19)/20个战士. 如果要 获得某个洞穴的金子,必须留下足够杀死所有虫子的战士数量, 即(x+19)/20个战士,然后这

数据结构与算法系列(2)基础排序算法

前言 在计算机中实现存储数据最普遍的两种操作就是排序和查找.这是从计算机产业初始就已经确认的 了.这意味着排序和查找也是计算机科学领域最值得研究的两种操作.本书提到的许 多数据结构的主要设计目的就是为了使排序和/或查找更加简单,同时也是为了数据在结构内的存 储更加有效. 本章会介绍有关数据排序和查找的基础算法.这些算法仅依赖数组作为数据结构,而且所采用的 "高级"编程技术只是递归.本章还介绍了用来非正式分析不同算法之间速度与效率的方 法,此方法贯穿全书. 1.排序算法 人们在日常生活中