您的位置:首页 > 其它

HDU 1069 Monkey and Banana (dp)

2017-07-15 21:23 330 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1069

题意:矩形嵌套的三维版,即长方体嵌套。有n种长方体,每种无限个,并且长方体可以滚动翻转。若长方体a的长和宽均小于长方体b的长和宽,则a可以摞在b的上面,求可以摞的最大高度 。

思路:首先建立关系,若i可以摞在j上面,则由i向j连一条有向边。另dp(i)表示以i为地基的长方体所能摞的最大高度,则问题转化为DAG上的动态规划问题。dp(i) = max{ dp(j) + h(i) }。

#include<cstdio>
#include<cstring>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;

struct Rec {
int l, w, h;
Rec(int l, int w, int h) : l(l), w(w), h(h){
if(this->l < this->w)
swap(this->l, this->w);
}
void out() {
printf("%d %d %d\n", l, w, h);
}
};

bool judge(const Rec& A, const Rec& B) {
return A.l < B.l && A.w < B.w;
}

vector<Rec> rec;
const int maxn = 200 + 10;
vector<int> G[maxn];
int d[maxn];

int dp(int u) {
if(!G[u].size()) return rec[u].h;
int &ans = d[u];
if(ans >= 0) return ans;
ans = 0;
for(int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
ans = max(ans, dp(v) + rec[u].h);
}
return ans;
}

int main() {
int n, x, y, z, kase = 0;
while(scanf("%d", &n) && n) {
rec.clear();
rec.push_back(Rec(0, 0, 0));
memset(d, -1, sizeof d);
for(int i = 0; i < n; i++) {
scanf("%d%d%d", &x, &y, &z);
rec.push_back(Rec(x, y, z));
rec.push_back(Rec(x, z, y));
rec.push_back(Rec(y, z, x));
}
for(int i = 1; i < rec.size(); i++) G[i].clear();
for(int i = 1; i < rec.size(); i++)
for(int j = 1; j < rec.size(); j++)
if(judge(rec[j], rec[i])) {
G[i].push_back(j);
}
int ans = 0;
for(int i = 1; i < rec.size(); i++)
ans = max(ans, dp(i));
printf("Case %d: maximum height = %d\n", ++kase, ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: