这个题可以转化为一个有向无环图,在其上寻找一条最长路径。 每一个box作为DAG上的一个顶点。如果box1可以嵌套到box2中,则在DAG中有一条有向边从box1指向box2 返回 Volume I 索引 返回总索引 // // 103 Stacking Boxes // Copyright (c) 2010 by Bo-wen Feng // balonfan@gmail.com // #include <set> #include <map> #include <list> #include <queue> #include <stack> #include <vector> #include <string> #include <sstream> #include <cstdio> #include <cmath> #include <limits> #include <utility> #ifndef ONLINE_JUDGE #include <fstream> std::ifstream cin("in.txt"); std::ofstream cout("out.txt"); // std::ofstream cout(stdout); #else #include <iostream> #endif typedef long long llong; typedef unsigned long long ullong; typedef long double ldouble; using namespace std; class Box { public: vector<int> d; int index; }; vector<Box> boxes; vector<vector<int> > adj; vector<int> nestLen; vector<int> prevBox; int nDim, nBox; bool compareBoxes(const Box& b1, const Box& b2) { for(int i = 0; i < nDim; ++i) if(b1.d[i] != b2.d[i]) return b1.d[i] < b2.d[i]; return false; } bool canNest(const Box& b1, const Box& b2) { for(int i = 0; i < nDim; ++i) if(b1.d[i] >= b2.d[i]) return false; return true; } int main(int argc, char* argv[]) { for(;;) { if(!(cin>> nBox>> nDim)) break; boxes.resize(nBox); adj.resize(nBox); nestLen.resize(nBox); prevBox.resize(nBox); fill(nestLen.begin(), nestLen.end(), 0); fill(prevBox.begin(), prevBox.end(), -1); for(int i = 0; i < nBox; ++i) { boxes[i].index = i + 1; boxes[i].d.resize(nDim); for(int j = 0; j < nDim; ++j) cin>> boxes[i].d[j]; sort(boxes[i].d.begin(), boxes[i].d.end()); adj[i].resize(nBox); fill(adj[i].begin(), adj[i].end(), 0); } sort(boxes.begin(), boxes.end(), compareBoxes); for(int i = 0; i < nBox; ++i) for(int j = 0; j < nBox; ++j) if(i != j && canNest(boxes[i], boxes[j])) adj[i][j] = 1; for(int i = 0; i < nBox; ++i) for(int j = i + 1; j < nBox; ++j) if(adj[i][j] && nestLen[i] + 1 > nestLen[j]) { nestLen[j] = nestLen[i] + 1; prevBox[j] = i; } int maxLenIndex = 0; for(int i = 1; i < nBox; ++i) if(nestLen[i] > nestLen[maxLenIndex]) maxLenIndex = i; cout<< (nestLen[maxLenIndex] + 1)<< "/n"; stack<int> boxPath; int x = maxLenIndex; while(x != -1) { boxPath.push(x); x = prevBox[x]; } if(!boxPath.empty()) { cout<< boxes[boxPath.top()].index; boxPath.pop(); } while(!boxPath.empty()) { cout<< " "<< boxes[boxPath.top()].index; boxPath.pop(); } cout<< "/n"; } return 0; }