http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=378
此题给出不同种类的矩形块(即给出x,y,z,代表其长宽高的元素),找出其长,宽均依次递减,并且最高的塔;
即是求最长下降子序列,只是权值为高。矩形块可以用无限多次。x,y,z,任意一个都可以作高,而其它两项为长宽。由于没有顺序要求,因此要将长,宽降序排列,这样就可以只比较前面的,而不需要顾及其它。
#include
#include
#include
using namespace std;
int dp[100];
int dir[3][3]={{0,1,2},{0,2,1},{1,2,0}};
int tow[100][3];
struct node
{
int l,w,h;
};
node to[100];
bool cmb(node a,node b)
{
if(a.l == b.l)
{
if(a.w == b.w)
return a.h > b.h;
return a.w > b.w;
}
return a.l > b.l;
}
bool ok(int x,int y)
{
if(to[x].l < to[y].l && to[x].w < to[y].w)
return true;
return false;
}
int main()
{
int n,i = 1;
while(scanf("%d",&n) == 1 && n)
{
int j,k;
n*=3;
for(j = 1; j <= n ;j+=3)
{
scanf("%d%d%d",&tow[j][0],&tow[j][1],&tow[j][2]);
for(k = 0; k < 3; k++)
{
to[j+k].l = tow[j][dir[k][0]];
to[j+k].w = tow[j][dir[k][1]];
to[j+k].h = tow[j][dir[k][2]];
if(to[j+k].l < to[j+k].w)
{
int t = to[j+k].l;
to[j+k].l = to[j+k].w;
to[j+k].w = t;
}
}
}
sort(to+1,to+n+1,cmb);/*排序*/
memset(dp,0,sizeof(dp));
int ans = 0;
//用“//”的是另一种方式,不过原理是一样的
for(j = 1 ;j <= n; j++)
{
dp[j] = to[j].h;
//int m = 0;
for(k = 1; k < j; k++){
if(ok(j,k))
{
/*如果前面符合条件的有权值与当前权值的和比当前的高度高,则更新为当前的高度*/
if(dp[j] < dp[k] + to[j].h)//if(dp[k] > m) //找到前面符合条件的最高的高度
{
//m = dp[k];
dp[j] = dp[k] + to[j].h;
}
}
}
//dp[j] = m + to[j].h; //当前高度更新
if(dp[j] > ans)/*找最高的高度*/
ans = dp[j];
}
printf("Case %d: maximum height = %d\n",i,ans);
i++;
}
}