ps:对于菜鸡来说,基础不代表简单 &_&
给N个 长宽高为xi,yi,zi的木块,问最高能叠多高;要求相邻的两个木块:上面木块的长和宽都必须严格小于它下面的;
分析:
首先像的还是枚举,只要枚举出所有情况的ans,保留最大的那个就是答案了;问题就在于怎么枚举。再深入分析一下,对于第i层木块来说,如果这个木块是最优解,那么它下面的第i-1层的这个木块肯定也要是最优解。所以如果说dp[x][y]是第i层应该放的那个木块,那么 dp[x][y] +=max{dp[x'][y'] | x'>x,y'>y};这样几乎就转化成数塔问题了,只要从底往上算上去,dp[最小的那个木块]就是答案;问题在于我们无法对dp[x][y]按照想要的顺序排序;
所以要像个办法转变,设一个结构体:
struct node { int x,y; // 长宽 int h,sum; //高和当前高度总值 }dp[maxn];分析可以发现一个性质:x'>x && y'>y 所以 x’+y' > x+y 就可以对dp数组桉树 x+y 排序了。
然后就可以利用前面的dp[x][y] +=max{dp[x'][y'] | x'>x,y'>y};
值得说的是,在最优解中,长宽相对最小的那个不一定非要放上去;所以答案不是dp[最小].sum,没考虑到这个因此wa了n次
<span style="font-size:10px;">/* *********************************************** Author :angon ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <stack> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; #define REP(i,k,n) for(int i=k;i<n;i++) #define REPP(i,k,n) for(int i=k;i<=n;i++) #define scan(d) scanf("%d",&d) #define scann(n,m) scanf("%d%d",&n,&m) #define LL long long #define maxn 1005 #define mod 100000007 struct node { int x,y; int h,sum; }dp[maxn]; bool cmp(node n1,node n2) { if(n1.x+n1.y!=n2.x+n2.y) //注意这个排序方式 return n1.x+n1.y>n2.x+n2.y; return n1.x>n2.x || (n1.x==n2.x && n1.y>n2.y); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n,x,y,z,ca=1; while(scanf("%d",&n) && n) { memset(dp,0,sizeof(dp)); int k=0; for(int i=0;i<n;i++) { scanf("%d%d%d",&x,&y,&z); dp[k].x=x; dp[k].y=y; dp[k].h=z; dp[k].sum=z; k++; dp[k].x=y; dp[k].y=z; dp[k].h=x; dp[k].sum=x; k++; dp[k].x=x; dp[k].y=z; dp[k].h=y; dp[k].sum=y; k++; } sort(dp,dp+k,cmp); for(int i=1;i<k;i++) { int temp=0; for(int j=0;j<i;j++) { if(dp[j].x > dp[i].x && dp[j].y > dp[i].y || dp[j].x > dp[i].y && dp[j].y > dp[i].x ) { temp=max(temp,dp[j].sum); } } dp[i].sum += temp; } int Max=0; REP(i,0,k) //一开始没考虑到这个wa了n次 Max=max(dp[i].sum,Max); printf("Case %d: maximum height = %d\n",ca++,Max); } return 0; }</span>