# [UVa-437] The Tower of Babylon

DAG建模基础；DP与DAG的关系

## 题意

n种长方体，各有无限个。可以横竖侧摆放。只有一个长方形的底面，长小于且宽小于令一个底面才可以叠在上面。问最多叠多高？

## Solution

### 求最长

DAG求最长路的本质是DP。设$dp[i]$表示从$i$出发的最长路，由于一定不会有环，所以用所有$i$连出去的点进行转移即可。换句话说这些连出去的点和$i$毫无关系，是个独立的子问题。DAG里是可以有重复的子问题的（树就没有）

## my code

/*By DennyQi 2019*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 10010;
const int MAXM = 20010;
const int INF = 0x3f3f3f3f;
inline int Max(const int a, const int b){ return (a > b) ? a : b; }
inline int Min(const int a, const int b){ return (a < b) ? a : b; }
int x = 0; int w = 1; register char c = getchar();
for(; c ^ '-' && (c < '0' || c > '9'); c = getchar());
if(c == '-') w = -1, c = getchar();
for(; c >= '0' && c <= '9'; c = getchar()) x = (x<<3) + (x<<1) + c - '0'; return x * w;
}
struct Cuboid{
int x,y,z;
}a[30001];
int n,N,Case,ans;
int first[30001],nxt[30001],to[30001],cost[30001],cnt,dp[30001],pre[30001];
bool vis[30001];
inline bool Nest(int i, int j){
if((a[i].x>a[j].x && a[i].y>a[j].y) || (a[i].x>a[j].y && a[i].y>a[j].x)) return 1;
return 0;
}
inline void add(int u, int v, int w){
cost[++cnt] = w, to[cnt] = v, nxt[cnt] = first[u], first[u] = cnt;
}
int Dfs(int u){
if(vis[u]) return dp[u];
vis[u] = 1;
for(int i = first[u]; i; i = nxt[i]){
if(Dfs(to[i]) + cost[i] > dp[u]){
dp[u] = dp[to[i]] + cost[i];
pre[u] = to[i];
}
}
return dp[u];
}
int main(){
n = N*3;
memset(vis,0,sizeof(vis));
memset(dp,0,sizeof(dp));
memset(first,0,sizeof(first));
for(int i = 1; i <= N; ++i){
a[i+N].x = a[i].x, a[i+N].y = a[i].z, a[i+N].z = a[i].y;
a[i+N*2].x = a[i].y, a[i+N*2].y = a[i].z, a[i+N*2].z = a[i].x;
}
for(int i = 1; i <= n; ++i){
}
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= n; ++j){
if(i == j) continue;
}