100722E The Bookcase

传送门

题目大意

给你一些书的高度和宽度,有一个一列三行书柜,要求放进去书后,三行书柜的高的和乘以书柜的宽度最小。问这个值最小是多少。

分析

我们可以先将所有书按照高度降序排好,这样对于每一层只要放过书高度边不会改变。我们设第一本书放在第一层,用dp[i][j][k]表示考虑到第i个,第二层的厚度为j,第三层的厚度为k的情况时书架的最小总高度是多少,如果j或k是0则代表这一层以前没放过书,然后根据这个转移就行了。由于空间不够我们使用滚动数组。注意由于至少有三本书,所以每一层至少会放一个(这样可以使答案更优)。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define gmin(x,y) x=min(x,y)
const int inf = 0x3f3f3f3f;
struct node {
      int h,w;
};
node d[100]; 
int dp[2][2200][2200],maxw[100];
inline bool cmp(const node x,const node y){return x.h>y.h;}
int main(){
      int n,m,i,j,k,t;
      scanf("%d",&t);
      while(t--){
          memset(maxw,0,sizeof(maxw));
          scanf("%d",&n);
        for(i=1;i<=n;i++){
          scanf("%d%d",&d[i].h,&d[i].w);
        }
        sort(d+1,d+n+1,cmp);
        maxw[2]=d[2].w;
        for(i=3;i<=n;i++)
          maxw[i]=maxw[i-1]+d[i].w;
        int now=0;
        memset(dp[now],0x3f,sizeof(dp[now]));
        dp[now][0][0]=d[1].h;
        for(i=2;i<=n;i++){
          now^=1;
          memset(dp[now],0x3f,sizeof(dp[now]));
          for(j=0;j<=maxw[i-1];j++)
            for(k=0;k+j<=maxw[i-1];k++)
              if(dp[now^1][j][k]<inf){
                gmin(dp[now][j][k],dp[now^1][j][k]);
                if(!j)gmin(dp[now][j+d[i].w][k],dp[now^1][j][k]+d[i].h);
                  else gmin(dp[now][j+d[i].w][k],dp[now^1][j][k]);
                if(!k)gmin(dp[now][j][k+d[i].w],dp[now^1][j][k]+d[i].h);
                  else gmin(dp[now][j][k+d[i].w],dp[now^1][j][k]);
              }
        }
        int ans=inf;
        for(i=1;i<=maxw[n];i++)
          for(j=1;j+i<=maxw[n];j++){
              k=maxw[n]-i-j+d[1].w;
              if(dp[now][i][j]<inf)
              gmin(ans,(dp[now][i][j])*max(i,max(j,k)));
          }
        printf("%d\n",ans);
      }
      return 0;
}
posted @ 2018-08-14 13:26  水题收割者  阅读(179)  评论(0编辑  收藏  举报