---恢复内容开始---
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 13003 Accepted Submission(s): 6843
题目链接:HDU 1069
题意:给出n种块的尺寸,用坐标x、y、z表示,当某一个块的两个比下面的块中某个两个坐标小的时候就可以把这个块叠上去,可以把块旋转一下使得三个坐标互相转变……
块的数量是无限的其实是吓唬人的,由于是要严格上升,显然三个已经把所有情况考虑了,四个肯定会跟某一种重复,然后每一个块都假设有三个,用O(n2)的方法求一种可以说是带权LIS的东西就行了
代码:
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int N=190;
struct info
{
int x;
int y;
int z;
bool operator<(const info &t)const
{
if(x!=t.x)
return x<t.x;
return y<t.y;
}
info(int xx,int yy,int zz):x(xx),y(yy),z(zz){}
info(){}
};
vector<info>arr;
int dp[N];
int main(void)
{
int n,i,j,x,y,z;
int q=1;
while (~scanf("%d",&n)&&n)
{
CLR(dp,0);
arr.clear();
for (i=0; i<n; ++i)
{
scanf("%d%d%d",&x,&y,&z);
arr.push_back(info(x,y,z));
arr.push_back(info(x,z,y));
arr.push_back(info(y,x,z));
arr.push_back(info(y,z,x));
arr.push_back(info(z,x,y));
arr.push_back(info(z,y,x));
}
sort(arr.begin(),arr.end());
int SZ=arr.size();
for (i=0; i<SZ; ++i)
{
int pre_max=0;
for (j=0; j<i; ++j)
{
if(arr[j].x<arr[i].x&&arr[j].y<arr[i].y&&dp[j]>pre_max)
pre_max=dp[j];
}
dp[i]=pre_max+arr[i].z;
}
printf("Case %d: maximum height = %d\n",q++,*max_element(dp,dp+SZ));//n^2算法这里就要取max,之前搞混了直接输出最后一个导致WA
}
return 0;
}
HDU 1069 Monkey and Banana(二维偏序LIS的应用)
原文:http://www.cnblogs.com/Blackops/p/5930755.html