• UVA12099 The Bookcase


    题目大意:

    n(3≤n≤70)n(3leq nleq 70)n(3n70)本书,每本书有一个高度HiH_iHi和一个宽度Wi(150≤Hi≤300,5≤Wi≤30)W_i(150leq H_ileq 300,5leq W_ileq 30)Wi(150Hi300,5Wi30)。 现在要构建一个3层的书架,你可以选择将nnn本书放在书架的哪一层。设3层高度(该层书的最大高度)之和为hhh,书架总宽度为www,要求h×wh imes wh×w(书架的面积)尽量小。

    输入格式:

    输入包含多组数据(不多于20个); 对于每组数据,第一行有一个正整数nnn,书的数量; 接下来nnn行每行两个正整数hi,wih_i,w_ihi,wi,分别代表书的高度、书的宽度。

    输出格式:

    对于每组测试数据,输出一行一个正整数,表示书架的最小面积。

    输入样例:

    2 4 220 29 195 20 200 9 180 30 6 256 20 255 30 254 15 253 20 252 15 251 9

    输出样例:

    18000 29796

    f[i][j][k]表示前i个书摆好后,第2层宽度为j,第3层宽度为k的最小高度和

    #include<bits/stdc++.h>
    #define inf 0x3f3f3f3f
    using namespace std;
    
    const int maxn = 2210;
    
    int f[2][maxn][maxn],n,sumw[maxn];
    
    struct node {
        int h,w;
        bool operator <(const node& a) const{
            return h>a.h;
        }
    }book[maxn];
    
    int main() {
        //freopen("in.txt","r",stdin);
        int t;scanf("%d",&t);
        while(t--) {
            scanf("%d",&n);
            sumw[0]=0;
            for(int i=1;i<=n;i++) {
                scanf("%d%d",&book[i].h,&book[i].w);
            }
            sort(book+1,book+1+n);
            for(int i=1;i<=n;i++) sumw[i]=sumw[i-1]+book[i].w;
            for(int hh=0;hh<=1;hh++)
            for(int i=0;i<=sumw[n];i++)
                for(int j=0;j+i<=sumw[n];j++) f[hh][i][j]=610;
            f[1][0][0]=0;
            for(int i=2;i<=n;i++) {
                for(int j=0;j<=sumw[i];j++){
                    for(int k=0;k+j<=sumw[i];k++) {
                        f[i%2][j][k]=f[(i-1)%2][j][k];
                        if(j-book[i].w>=0)f[i%2][j][k]=min(f[i%2][j][k],f[(i-1)%2][j-book[i].w][k]+(j-book[i].w==0?book[i].h:0));
                        if(k-book[i].w>=0)f[i%2][j][k]=min(f[i%2][j][k],f[(i-1)%2][j][k-book[i].w]+(k-book[i].w==0?book[i].h:0));    
                    }
                }
            }
            int ans=inf;
            for(int i=1;i<=sumw[n];i++) {
                for(int j=1;j+i<=sumw[n];j++) {
                    if(f[n%2][i][j]!=610)
                    ans=min(ans,(f[n%2][i][j]+book[1].h)*max(i,max(j,sumw[n]-i-j)));
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    货币
    沙漏
    秋季学习总结
    三个老师
    介绍自己
    redis 的部分配置
    第二次博客作业
    第一次阅读作业
    shell_通配符
    shell_/dev/null,>和&
  • 原文地址:https://www.cnblogs.com/plysc/p/10882380.html
Copyright © 2020-2023  润新知