题意:
小孩子玩积木堆房子的情景:
每组测试数据第一行给出n,代表接下来有n块砖;
接下来n行,每行给出砖的长,宽,高,属性(a,b,c,d);
属性d:d=0:该砖的长度和宽度(a,b)要比垫在他下面的砖的长,宽大或者相等;就是长>=长,宽>=宽
d=1:改砖的宽度和长度要比下面的砖的长度大或者相等,同时,该砖的宽度值和面积值要比下面的砖的面积值大;即长>=长,宽>=宽,面积>面积。也就是长>=长&&宽>=宽&&(长>长||宽>宽)
d=2:该砖的长度和宽度(a,b)要比垫在他下面的砖的长,宽大(严格大于);长>长,宽>宽。
要求输出该给出的所有的砖块所能听堆砌的最大高度。
排序的原因是让数组后面的砖头一定可以叠在前面的砖头上。
dp[i]表示以i为最上面那一块砖头所能迭的最大高度。
状态转移方程: dp[i] = max(dp[i],dp[j] + b[i].z);
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; struct block{ __int64 x,y,z; int d; bool operator < (const block & cmp) const{ if(x != cmp.x) return x < cmp.x; if(y != cmp.y) return y < cmp.y; return d > cmp.d; } }b[1010]; int n; __int64 dp[1010]; int main() { while(~scanf("%d",&n) && n){ for(int i = 1; i <= n; i ++){ scanf("%I64d%I64d%I64d%d",&b[i].x,&b[i].y,& b[i].z,& b[i].d); //为什么要交换呢? if(b[i].x < b[i].y) swap(b[i].x,b[i].y); } sort(b + 1, b + 1 + n); __int64 ans = b[1].z;// for(int i = 1; i <= n; i ++){ dp[i] = b[i].z; ans = max(dp[i],ans); } //dp[i]表示最后一个是i的最大高度 for(int i = 2; i <= n; i ++){ if(b[i].d == 0){ for(int j = 1; j < i; j ++){ if(b[i].x >= b[j].x && b[i].y >= b[j].y) dp[i] = max(dp[i],dp[j] + b[i].z); } }else if(b[i].d == 1){ for(int j = 1; j < i; j ++){ if(b[i].x >= b[j].x && b[i].y >= b[j].y &&(b[i].y>b[j].y||b[i].x>b[j].x) ) dp[i] = max(dp[i],dp[j] + b[i].z); } }else{ for(int j = 1; j < i; j ++){ if(b[i].x > b[j].x && b[i].y > b[j].y) dp[i] = max(dp[i],dp[j] + b[i].z); } } if(ans < dp[i]) ans = dp[i]; } printf("%I64d\n",ans); } return 0; }