UVA - 12099 The Bookcase

No wonder the old bookcase caved under the massive piles of books Tom had stacked on it. He had better build a new one, this time large enough to hold all of his books. Tom finds it practical to have the books close at hand when he works at his desk. Therefore, he is imagining a compact solution with the bookcase standing on the back of the desk. Obviously, this would put some restrictions on the size of the bookcase, it should preferably be as small as possible. In addition, Tom would like the bookcase to have exactly three shelves for aesthetical reasons. Wondering how small his bookcase could be, he models the problem as follows. He measures the height hi and thickness ti of each book i and he seeks a partition of the books in three non-empty sets S1, S2, S3 such that (∑3 j=1 maxi∈Sj hi) × (max3 j=1 ∑ i∈Sj ti) is minimized, i.e. the area of the bookcase as seen when standing in front of it (the depth needed is obviously the largest width of all his books, regardless of the partition). Note that this formula does not give the exact area of the bookcase, since the actual shelves cause a small additional height, and the sides cause a small additional width. For simplicity, we will ignore this small discrepancy. Thinking a moment on the problem, Tom realizes he will need a computer program to do the job

Input

The input begins with a positive number on a line of its own telling the number of test cases (at most 20). For each test case there is one line containing a single positive integer N, 3 ≤ N ≤ 70 giving the number of books. Then N lines follow each containing two positive integers hi , ti , satisfying 150 ≤ hi ≤ 300 and 5 ≤ ti ≤ 30, the height and thickness of book i respectively, in millimeters.

Output

For each test case, output one line containing the minimum area (height times width) of a three-shelf bookcase capable of holding all the books, expressed in square millimeters.

Sample Input

2

4

220 29

195 20

200 9

180 30

6

256 20

255 30

254 15

253 20

252 15

251 9

Sample Output

18000 29796

  这个题目在状态的构造上,十分用心,如果我们考虑暴力DP那么显然要记下6个东西,就是每行的长和高,当然首先空间上过不去,其次,转移也十分复杂,那么考虑优化我们的状态。

  首先只要记下两个宽和一个高就可以了,因为如果我们知道两个宽,就可以用总和减去两个宽得到下一个宽,然后有一个高是必定不用记下的,因为他一定是最高的那本书,然后第一维记处理到那本书,可以滚动,数组里存剩下的一个高,但即使优化到这个地步还是会暴空间!怎么办?

  我们把那两个高之和的最小值存在数组了,这样就只有三维(相当于两维),即:设dp[i][j][k],表示dp到第i本书,第二列的宽度是j,第三列的宽度是k的二三列的最小高度和,这个为什么可以转移呢?我们考虑将每本书按照高度排序!那么第一本(最高的一本)我们强制放在第一列,而且只要第二列,第三列有书,因为我们是从高到低放的所以一定更新不了最大当列的最高值,进而更新不了他们的高度和!

  转移就是枚举本书分放到第1,2,3,层进行转移。

代码:

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#define MAXN 2150
#define ll long long
using namespace std;
struct book{
    int h,w;
}a[80];
int f[MAXN][MAXN],dp[2][MAXN][MAXN],sum[80];
int n,inf;

bool cmp(book x,book y){
    return x.h>y.h;
}

int main(){
    int t;cin>>t;
    while(t--){
        memset(f,0,sizeof(f));
        memset(dp,127,sizeof(dp));inf=dp[0][0][0];
        memset(a,0,sizeof(a));
        memset(sum,0,sizeof(sum));
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d%d",&a[i].h,&a[i].w);
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i].w;
        for(int i=1;i<=n;i++){
            f[0][a[i].h]=a[i].h;
        }
        dp[0][0][0]=0;
        int now=0,last=1;
        for(int i=1;i<n;i++){
            now^=1,last^=1;
            memset(dp[now],127,sizeof(dp[now]));
            for(int j=0;j<=sum[i];j++)
                for(int k=0;k<=sum[i];k++){
                    if(dp[last][j][k]==inf) continue;
                    if(j+k>sum[i]) break;
                    dp[now][j+a[i+1].w][k]=min(dp[now][j+a[i+1].w][k],dp[last][j][k]+f[j][a[i+1].h]);
                    dp[now][j][k+a[i+1].w]=min(dp[now][j][k+a[i+1].w],dp[last][j][k]+f[k][a[i+1].h]);
                    dp[now][j][k]=min(dp[now][j][k],dp[last][j][k]);
                }
        }
        int ans=inf;
        for(int i=0;i<=sum[n];i++)
        for(int j=0;j<=sum[n];j++){
            if(i+j>sum[n]) break;
            if(dp[now][i][j]==inf) continue;
            if(i == 0 || j == 0)  continue;
            ans = min(ans, (dp[now][i][j] + a[1].h) * max(j, max(i, sum[n]-j-i)));
        }
        printf("%d\n",ans);
    }
}
时间: 2024-11-16 19:14:02

UVA - 12099 The Bookcase的相关文章

UVa 12099 The Bookcase - 动态规划

题目大意 给定一些书,每个书有一个高度和宽度,然后将它们放到一个三层的书架里(要求每一层都不为空).定义书架的大小为每层最大的高度和 乘 每层宽度和的最大值.求最小的书架大小. 显然动态规划(直觉,没有为什么). 然后确定状态,f[i][j][k]表示正在考虑第i本书,第2层的宽度和为j,第3层的宽度和为k(这样第一层的宽度和就可以计算出来)最小的高度和.然后发现无处下手...难道要把所有高度记录下来? 现在来考虑优化,最简单的一种就是去除无用.重复状态. step 1 >> 放书的顺序和结果

UVa 12099 The Bookcase (DP)

题意:有 n 本书,每本书有一个高度和宽度,然后让你制作一个3层的书架,可以放下所有的书,并且要高*宽尽量小. 析:先把所有的书按高度进行排序,然后dp[i][j][k] 表示 前 i 本书,第二 层的宽度是 j,第三层的宽度是 k,第二层和第三层的高度最小,首先我们可以先最高的那本书放到第一层,那么这一层的高度就确定了,同理,在放第二层和第三层的时候,如果是第一本书,那么这一层的高度就已经确定了,为什么不表示第一层的宽度呢,因为总宽度是确定的,如果第二层的宽度和第三层的宽度知道了,那么第一层也

【暑假】[深入动态规划]UVa 10618 The Bookcase

UVa 12099  The Bookcase 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=42067 思路:   将n本书分配到三层,使得形成的书架w*h最小 提前将书籍按照高度排序,因为无论第一本书(最高的书)无论放在那一层都会被考虑到,所以规定将它放在第一层,且第二层比第三层高. 因为从大到小排序的关系,只要jk==0那么新加入的书i就是该层的高度,否则高度不变. 设d[i][j][k]表示考虑过i本书第二

[SinGuLaRiTy] 动态规划题目复习

[SinGuLaRiTy-1026] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. [UVA 1025] A Spy in the Metro 题目描述 特工玛利亚被送到S市执行一个特别危险的任务.她需要利用地铁完成他的任务,S市的地铁只有一条线路运行,所以并不复杂. 玛利亚有一个任务,现在的时间为0,她要从第一个站出发,并在最后一站的间谍碰头.玛利亚知道有一个强大的组织正在追踪她,她知道如果一直呆在一个车站,她会有很大的被抓的风险,躲

UVA - 10239 The Book-shelver&amp;#39;s Problem

Description Problem D The Book-shelver's Problem Input: standard input Output: standard output Time Limit: 5 seconds Memory Limit: 32 MB You are given a collection of books, which must be shelved in a library bookcase ordered (from top to bottom in t

UVA - 10239 The Book-shelver&#39;s Problem

Description Problem D The Book-shelver's Problem Input: standard input Output: standard output Time Limit: 5 seconds Memory Limit: 32 MB You are given a collection of books, which must be shelved in a library bookcase ordered (from top to bottom in t

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 10341 Solve It

Problem F Solve It Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of multiple test cases and te

UVA 11014 - Make a Crystal(容斥原理)

UVA 11014 - Make a Crystal 题目链接 题意:给定一个NxNxN的正方体,求出最多能选几个整数点.使得随意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O).那么全部点就是f(1),之后要去除掉共线的,就是扣掉f(2), f(3), f(5)..f(n).n为素数.由于这些素数中包括了合数的情况,而且这些点必定与f(1)除去这些点以外的点共线,所以扣掉.可是扣掉后会扣掉一些反复的.比方f(6)在f