[簡單DP]Monkey and Banana HDU - 1069
題意:給你N種類型長方體,長寬高分別爲X,Y,Z,每種長方體都可以無限制的使用。現在讓你把他們一個接着一個組成一個儘可能高的塔,每一層只能有一個長方體,並且上一層的長方體的長和寬要嚴格大於它下面長方體的長和寬。
分析:塔的高度只和用多少種長方體有關,因此我們可以使用dp[i]表示使用i種長方體可以組成的最大高度,塔底的長和寬肯定是越大越好,所以需要對長方體按長寬排序。很顯眼,dp[i]的值和dp[1]——dp[i-1]有關,直接使用兩個for循環枚舉即可。還要注意一點,長方體的長寬高是相對的,我們可以隨意擺放。
狀態轉移方程: dp[i]=max(dp[i],dp[j]+num[i].z);
代碼:
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<stdio.h>
#include<queue>
using namespace std;
struct node
{
int x,y,z;
};
bool cmp(node a,node b)
{
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
int main()
{
int n;
int cnt=1;
while(scanf("%d",&n)&&n)
{
node num[200];
int k=1;
for(int i=0;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
num[k].x=x;num[k].y=y;num[k++].z=z;
num[k].x=y;num[k].y=z;num[k++].z=x;
num[k].x=z;num[k].y=x;num[k++].z=y;
num[k].x=x;num[k].y=z;num[k++].z=y;
num[k].x=y;num[k].y=x;num[k++].z=z;
num[k].x=z;num[k].y=y;num[k++].z=x;
}
sort(num+1,num+k,cmp);
int dp[200];
memset(dp,0,sizeof(dp));
int maxh=0;
for(int i=1;i<k;i++)
{
dp[i]=num[i].z;
for(int j=1;j<i;j++)
{
if((num[j].x<num[i].x)&&(num[j].y<num[i].y))
{
dp[i]=max(dp[i],dp[j]+num[i].z);
}
}
if(maxh<dp[i])
maxh=dp[i];
}
printf("Case %d: maximum height = %d\n",cnt++,maxh);
}
return 0;
}