Leetcode 1691. 堆疊長方體的最大高度(拓撲排序 + DP)
Description
Solution
一個立方體可以任意翻轉, 我們可以當成多個不同的立方體看待。
問題轉化為:有最多N*6個立方體, 最高能壘多高
考慮DP[i], 第i個立方體放在最上面時的最大高度, 發現當前的狀態是由所有可以壘在其下面的立方體轉移過來的,所以我們考慮一邊拓撲排序一邊DP
Code
class Solution {
public:
#define N 202
struct cube{
int a,b,c;
};
vector<cube>num;
inline void init() {
num.clear();
}
bool vis[N][N][N];
inline void emp(int a,int b,int c) {
vis[a][b][c] = vis[a][c][b] = vis[b][a][c] = vis[b][c][a] = vis[c][a][b] = vis[c][b][a] = false;
}
int d[N*3], dp[N*3];
vector<int>edge[N*3];
int used[N][N][N], val[N*3];
bool check(int i,int j) {
if(num[i].a >= num[j].a && num[i].b >= num[j].b && num[i].c >= num[j].c) {
return true;
}
return false;
}
inline void add(int i,int j) {
edge[i].push_back(j);
++d[j];
}
int solve() {
int n = num.size();
for(int i = 0;i < n;++i) edge[i].clear(), d[i] = 0, used[num[i].a][num[i].b][num[i].c] = 0;
vector<cube>tmp;
for(int i = 0;i < n;++i) {
int a = num[i].a, b = num[i].b, c = num[i].c;
if(!used[a][b][c]) {
tmp.push_back((cube){a,b,c});
} else {
}
used[a][b][c] += num[i].c;
}
num.clear();
for(auto x : tmp) {
num.push_back(x);
} tmp.clear();
n = num.size();
for(int i = 0;i < n;++i) {
dp[i] = val[i] = used[num[i].a][num[i].b][num[i].c];
for(int j = 0;j < n;++j) {
if(i == j) continue;
if(check(i,j)) add(i,j);
}
}
queue<int>q;
for(int i = 0;i < n;++i) if(!d[i]) {q.push(i);}
int res = 0;
while(!q.empty()) {
int u = q.front();q.pop();
for(int i = 0;i < edge[u].size();++i) {
int v = edge[u][i];
dp[v] = max(dp[v], dp[u] + val[v]);
if(--d[v] == 0) q.push(v);
}
}
for(int i = 0;i < n;++i) res = max(res, dp[i]);
return res;
}
int maxHeight(vector<vector<int>>& cuboids) {
init();
for(int i = 0;i < cuboids.size();++i) {
int a = cuboids[i][0], b = cuboids[i][1], c = cuboids[i][2];
num.push_back((cube){a,b,c}), vis[a][b][c] = true;
if(!vis[a][c][b]) num.push_back((cube){a,c,b}), vis[a][c][b] = true;
if(!vis[b][a][c]) num.push_back((cube){b,a,c}), vis[b][a][c] = true;
if(!vis[b][c][a]) num.push_back((cube){b,c,a}), vis[b][c][a] = true;
if(!vis[c][a][b]) num.push_back((cube){c,a,b}), vis[c][a][b] = true;
if(!vis[c][b][a]) num.push_back((cube){c,b,a}), vis[c][b][a] = true;
emp(a,b,c);
}
int res = solve();return res;
}
};
相關文章
- POJ 3249-Test for Job(拓撲排序&&DP)排序
- 拓撲排序排序
- 洛谷P3953 逛公園(dp 拓撲排序)排序
- 【Tarjan 拓撲排序 dp】P3387 【模板】縮點排序
- 拓撲排序,YYDS排序
- 拓撲排序模板排序
- 拓撲排序小結排序
- 圖論——拓撲排序圖論排序
- 筆記:拓撲排序筆記排序
- Reward (圖論+拓撲排序)圖論排序
- 拓撲排序 - Topological Sort排序
- 拓撲排序核心程式碼排序
- HDU 4857 逃生(拓撲排序)排序
- AOV網與拓撲排序排序
- DFS實現拓撲排序排序
- 【筆記/模板】拓撲排序筆記排序
- 有向圖的拓撲排序——DFS排序
- 拓撲排序就這麼回事排序
- HDU4857逃生(拓撲排序)排序
- 紙上談兵: 拓撲排序排序
- poj 1094 拓撲排序排序
- poj1094 拓撲排序排序
- 演算法-圖論-拓撲排序演算法圖論排序
- 圖的拓撲排序詳解與實現排序
- 圖解拓撲排序+程式碼實現圖解排序
- 【圖論】拓撲排序+優先佇列圖論排序佇列
- HDU 5438 Ponds (拓撲排序應用+DFS)排序
- CF 274D Lovely Matrix(拓撲排序)排序
- HDU 4857-逃生(反向拓撲排序-按條件排序)排序
- 記憶體堆疊記憶體
- 圖(3)--拓撲排序與關鍵路徑排序
- hdu 1811 並查集+拓撲排序並查集排序
- (set+拓撲排序) CF1572A Book排序
- 拓撲排序 (BFS )DAG (有向無環圖)排序
- VOL.2 拓撲排序與關鍵路徑排序
- POJ1094[有向環 拓撲排序]排序
- csdn hud 2094 拓撲排序 已經AC排序
- 拓撲排序詳解(梅開二度之dfs版按字典序輸出拓撲路徑+dfs版輸出全部拓撲路徑排序