UVA 437 The Tower of Babylon(DAG上的动态规划)
题目大意是根据所给的有无限多个的n种立方体,求其所堆砌成的塔最大高度。
方法1,建图求解,可以把问题转化成求DAG上的最长路问题
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = ;
struct Node{
int x;
int y;
int z;
Node(int x,int y,int z):x(x),y(y),z(z){}
Node(){}
bool operator < (const Node &n)const{
return (x < n.x&& y < n.y) || (x < n.y&& y < n.x);
}
};
vector<Node> vec;
int n;
int d[maxn*];
int G[maxn*][maxn*];
int dp(int i,int h){
int & ans = d[i];
if(ans>)return ans;
ans = h;
for(int j = ; j < n*; j++)if(G[i][j]){
ans = max(ans,dp(j,vec[j].z)+h);
}
return ans;
}
int main(){
int cnt = ;
while(scanf("%d",&n)==&&n){
vec.clear();
memset(G,,sizeof(G));
memset(d,,sizeof(d));
for(int i = ; i< n; i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
vec.push_back(Node(x,y,z));
vec.push_back(Node(x,z,y));
vec.push_back(Node(z,y,x));
}
sort(vec.begin(),vec.end()); for(int i = ;i < n*; i++){
for(int j = ; j < n*; j++){
if(vec[i] < vec[j])
G[i][j] = ;
}
}
int result = -;
for(int i = ; i < n* ;i++){
result = max(result,dp(i,vec[i].z));
}
printf("Case %d: maximum height = %d\n",++cnt,result);
}
return ;
}
方法2,转化成最长递增子序列问题求解
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = ;
struct Node{
int x;
int y;
int z;
Node(int x,int y,int z):x(x),y(y),z(z){}
Node(){}
bool operator < (const Node &n)const{
return (x < n.x&& y < n.y) || (x < n.y&& y < n.x);
}
};
bool cmp(Node a,Node b){
return a.x*a.y < b.x*b.y;
}
vector<Node> vec;
int n;
int d[maxn*];
int LIS(int n){
//d[i] = max{hi,d[j]}i>j ,A[i]>A[j]
int t = ;
for(int i = ; i < n*; i++){
d[i] = vec[i].z;
for(int j = ; j < i; j++)
if(vec[j] < vec[i])
d[i] = max(d[i],d[j]+vec[i].z);
if(d[i] > t) t = d[i];
}
return t;
}
int main(){
int cnt = ;
while(scanf("%d",&n)==&&n){
vec.clear();
memset(d,,sizeof(d));
for(int i = ; i< n; i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
vec.push_back(Node(x,y,z));
vec.push_back(Node(x,z,y));
vec.push_back(Node(z,y,x));
}
sort(vec.begin(),vec.end(),cmp);
printf("Case %d: maximum height = %d\n",++cnt,LIS(n));
}
return ;
}
方法二要注意一点,我sort序列的时候用了一个cmp函数,他是根据立方体的底面积对立方体进行排序的。为什么不采用和方法一一样的排序方式呢?
因为a.x <b.x&&a.y<b.y
或 a.y<b.x&&a.x<b.y
=>Sa <Sb
所以在塔上面的立方体的底面积一定比下面的小。
UVA 437 The Tower of Babylon(DAG上的动态规划)的更多相关文章
- UVa 437 The Tower of Babylon(经典动态规划)
传送门 Description Perhaps you have heard of the legend of the Tower of Babylon. Nowadays many details ...
- UVa 437 The Tower of Babylon
Description Perhaps you have heard of the legend of the Tower of Babylon. Nowadays many details of ...
- UVa 437 The Tower of Babylon(DP 最长条件子序列)
题意 给你n种长方体 每种都有无穷个 当一个长方体的长和宽都小于还有一个时 这个长方体能够放在还有一个上面 要求输出这样累积起来的最大高度 由于每一个长方体都有3种放法 比較不好控制 ...
- UVA 437 "The Tower of Babylon" (DAG上的动态规划)
传送门 题意 有 n 种立方体,每种都有无穷多个. 要求选一些立方体摞成一根尽量高的柱子(在摞的时候可以自行选择哪一条边作为高): 立方体 a 可以放在立方体 b 上方的前提条件是立方体 a 的底面长 ...
- DP(DAG) UVA 437 The Tower of Babylon
题目传送门 题意:给出一些砖头的长宽高,砖头能叠在另一块上要求它的长宽都小于下面的转头的长宽,问叠起来最高能有多高 分析:设一个砖头的长宽高为x, y, z,那么想当于多了x, z, y 和y, x, ...
- UVA - 437 The Tower of Babylon(dp-最长递增子序列)
每一个长方形都有六种放置形态,其实可以是三种,但是判断有点麻烦直接用六种了,然后按照底面积给这些形态排序,排序后就完全变成了LIS的问题.代码如下: #include<iostream> ...
- UVA 437 The Tower of Babylon巴比伦塔
题意:有n(n≤30)种立方体,每种有无穷多个.要求选一些立方体摞成一根尽量高的柱子(可以自行选择哪一条边作为高),使得每个立方体的底面长宽分别严格小于它下方立方体的底面长宽. 评测地址:http:/ ...
- UVa 103 Stacking Boxes --- DAG上的动态规划
UVa 103 题目大意:给定n个箱子,每个箱子有m个维度, 一个箱子可以嵌套在另一个箱子中当且仅当该箱子的所有的维度大小全部小于另一个箱子的相应维度, (注意箱子可以旋转,即箱子维度可以互换),求最 ...
- UVA 1025 "A Spy in the Metro " (DAG上的动态规划?? or 背包问题??)
传送门 参考资料: [1]:算法竞赛入门经典:第九章 DAG上的动态规划 题意: Algorithm城市的地铁有 n 个站台,编号为 1~n,共有 M1+M2 辆列车驶过: 其中 M1 辆列车从 1 ...
随机推荐
- Alert Log删除
标题:Renaming or Deleting the Alert Log While an Oracle Instance is Up & Running (文档 ID 74966.1) Q ...
- selenium之Xpath定位
1. 绝对定位: driver.find_element_by_xpath("/html/body/div[x]/form/input") x 代表第x个 div标签,注意,索引从 ...
- java中的==、equals()源码分析
浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...
- C#实现文件上传以及文件下载
public ActionResult Upload() { // var pathUrl = "http://" + Request.Url.Authority; var fil ...
- C++继承和派生练习(一)--关于从people(人员)类派生出student(学生)类等
. 从people(人员)类派生出student(学生)类 添加属性:班号char classNO[]:从people类派生出teacher(教师)类, 添加属性:职务char principalsh ...
- 通过xshell在linux上安装tomcat8
通过xshell在linux上安装tomcat8 0)去官网下载linux版压缩包(点击去下载) 1)创建存放tomcat的文件夹 mkdir /usr/tomcat 2)通过xftp将其放置到指定文 ...
- (第03节)三种ApplcationContext的实现
- java的动态验证码单线设计
1.java的动态验证码我这里将介绍两种方法: 一:根据java本身提供的一种验证码的写法,这种呢只限于大家了解就可以了,因为java自带的模式编写的在实际开发中是没有意义的,所以只供学习一下就可以了 ...
- MAthJax入门教程(五分钟上手)
最近在研究,在页面中显示一些数学公式.搞得我很头疼. 据说MathJax会统一这已领域.所以去学了学.网上教程特别多.繁杂. 说的清楚的特别少. 我是这么跑通的,: 1.在官网下载代码地址为:http ...
- Node.js(一)----安装
1.下载 地址 https://nodejs.org/en/download/ 注: 系统为ubuntu 下载的源码包 tar.gz 或者 wget https://nodejs.org/dist/v ...