类似LIS的思想,只能用LIS的 O(n2)的算法,O(nlogn)的算法用不了,因为每个数值加了权值!其实我感觉可以用树形dp的,因为他们是偏序关系,可以建一个hash图,复杂度O(nlogn)绝对可以,然后dp过程只要O(n)的复杂度,可以每次判断hash图中被自己覆盖元素的最大的那个值,然后加上自己的权值,就能推出自己所能达到的最大值,这样dp只要扫一遍就可以了,总复杂度O(nlogn)。。。。。那个。。。有谁知道怎么建hash图不
#include<iostream> #include<vector> #include<algorithm> using namespace std; struct pp { int x,y,h; bool operator == (const pp& cmp) const { if(x==cmp.x && y==cmp.y) { return true; } else { return false; } } bool operator < (const pp& cmp) const { if(x!=cmp.x) { return x<cmp.x; } else if(y!=cmp.y) { return y<cmp.y; } else { return h<cmp.h; } } }p; int a,b,c,N,ca,tmax,maxh,dp[200]; vector<pp>va,vb; inline void pushinto() { p.x=a; p.y=b; p.h=c; va.push_back(p); // a b c swap(p.x,p.y); va.push_back(p); // b a c swap(p.y,p.h); va.push_back(p); // b c a swap(p.x,p.y); va.push_back(p); // c b a swap(p.y,p.h); va.push_back(p); // c a b swap(p.x,p.y); va.push_back(p); // a c b return ; } void uniquecopy() { sort(va.begin(),va.end()); vb.push_back(va[0]); for(int i=1;i<va.size();i++) { if( va[i] == vb.back() ) { if(va[i].h > vb.back().h) { vb.back().h = va[i].h; } } else { vb.push_back(va[i]); } } return ; } void dpstart() { memset(dp,sizeof(dp)); maxh=dp[0]=vb[0].h; for(int i=1;i<vb.size();i++) { tmax=0; for(int j=i-1;j>=0;j--) { if(vb[i].y > vb[j].y && vb[i].x != vb[j].x) { if(dp[j]>tmax) { tmax=dp[j]; } } } dp[i]=vb[i].h+tmax; if(dp[i]>maxh) { maxh=dp[i]; } } printf("Case %d: maximum height = ",ca++); cout<<maxh<<endl; return ; } int main() { ca=1; while(cin>>N) { if(0 == N) { break; } va.clear(); vb.clear(); for(int i=1;i<=N;i++) { cin>>a>>b>>c; pushinto(); } uniquecopy(); dpstart(); } return 0; }