zoukankan      html  css  js  c++  java
  • 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
    ",ans);
          }
          return 0;
    }
  • 相关阅读:
    Delphi中Android运行和JNI交互分析
    C++ 中内存分配和回收
    Delphi Android程序启动过程
    Delphi XE的RTTI增强,动态Hook某些内部事件
    Win7下超级管理员创建普通权限任务
    再探Delphi2010 Class的构造和析构顺序
    Delphi2010新发现-类的构造和析构函数功能
    【背包专题】01背包
    Delphi2010的RTTI增强
    用WebBrowser实现HTML界面的应用和交互 good
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9474064.html
Copyright © 2011-2022 走看看