The Bookcase

题意:

有n本宽w高h的书,向三层书架上放,每层不能为空,求占用的整体的最小面积(总高度*三层中最宽的)

分析:

不太好想,dp[i][j]表示第一层宽度为i第二层为j放的最小高度

dp[i][j]=min(dp[i-w[i]][j],dp[i][j-w[i]])放在第一、二层取最小,当i,j放的是第一本书的时候要加上相应的高度,先按高度升序排列保证正确性。

最后遍历求最小面积

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<11
#define All 1,N,1
#define read freopen("in.txt", "r", stdin)
const ll  INFll = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 0x7ffffff;
const int mod =  1000000007;
struct book{
    int h,w;
}b[71];
int dp[2111][2111],sum,n;
bool cmp(book x,book y){
  if(x.h==y.h)return x.w<y.w;
  return x.h>y.h;
}
void solve(){
    for(int i=0;i<=sum;++i)
        for(int j=0;j<=sum;++j)
        dp[i][j]=INF;
    dp[0][0]=0;
    int tw=0;
    for(int i=1;i<n;++i){
        for(int j=tw;j>=0;--j)
        for(int k=tw;k>=0;--k){
            if(dp[j][k]==INF||j+k>tw)continue;
            int tmp=0;
            if(j==0)
                tmp=b[i].h;
            dp[j+b[i].w][k]=min(dp[j+b[i].w][k],dp[j][k]+tmp);
            tmp=0;
            if(k==0)
                tmp=b[i].h;
            dp[j][k+b[i].w]=min(dp[j][k+b[i].w],dp[j][k]+tmp);
        }
        tw+=b[i].w;
    }
    int mina=INF;
    for(int i=1;i<=sum;++i)
    for(int j=1;j<=sum;++j){
        if(dp[i][j]==INF||i+j>=sum)continue;
        int k=sum-i-j;
        int mw=max(max(i,j),k);
        mina=min(mina,(dp[i][j]+b[0].h)*mw);
    }
    printf("%d\n",mina);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        sum=0;
        for(int i=0;i<n;++i){
            scanf("%d%d",&b[i].h,&b[i].w);
            sum+=b[i].w;
        }
        sort(b,b+n,cmp);
        solve();
    }
return 0;
}
时间: 2024-11-07 00:24:48

The Bookcase的相关文章

codeforces 707D:Persistent Bookcase

Description Recently in school Alina has learned what are the persistent data structures: they are data structures that always preserves the previous version of itself and access to it when it is modified. After reaching home Alina decided to invent

【Codeforces-707D】Persistent Bookcase DFS + 线段树

D. Persistent Bookcase Recently in school Alina has learned what are the persistent data structures: they are data structures that always preserves the previous version of itself and access to it when it is modified. After reaching home Alina decided

新概念英语(1-37)Making a bookcase

What is Susan's favourite color ? A:You're working hard, Georage. What are you doing? B:I am making a bookcase. Give me that hammer please, Dan. A:Which hammer? This one? B:No, not that one. The big one. A:Here you are. B:Thanks, Dan. A:What are you

CodeForces #368 div2 D Persistent Bookcase DFS

题目链接:D Persistent Bookcase 题意:有一个n*m的书架,开始是空的,现在有k种操作: 1 x y 这个位置如果没书,放书. 2 x y 这个位置如果有书,拿走. 3 x 反转这一行,即有书的位置拿走,没书的位置放上书. 4 x 返回到第x步操作之后的书架. 现在给出q个操作,询问每次操作之后书架上书的数量. 思路: 开始没有思路.后来被告知dfs. [词不达意.参考:http://blog.csdn.net/zyjhtutu/article/details/5227949

【暑假】[深入动态规划]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本书第二

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.

BZOJ 1933 [Shoi2007]Bookcase 书柜的尺寸 ——动态规划

状态设计的方法很巧妙,六个值 h1,h2,h3,t1,t2,t3,我们发现t1,t2,t3可以通过前缀和优化掉一维. 然后考虑把h留下还是t留下,如果留下h显然t是会发生改变的,一个int存不下. 如果按照h降序排序,然后计算的时候存总的高度值,就很方便转移了. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std;

[Shoi2007]Bookcase 书柜的尺寸 dp

这道dp算是同类型dp中比较难的了,主要难点在于设置状态上: 如果像平时那样设置,必定爆空间没商量: 下面是一种思路: 先把输入进来的数据按h从大到小排序,这样就可以大大减少状态数, 然后设f[i][j][k]为前i本书第一个书柜厚度j,第二个书柜厚度k,第三个书柜厚度sum[i]-j-k的h最大值得最小和: 这样一是将h放在了里面,相当于一个方程思想,因为s可以由h,t算出来: 二是转移的时候,如果j,k或sum[i]-j-k为0,直接加上h,因为前面的h比后面的大,方便了转移: 但我最后也是

CodeForces 707D Persistent Bookcase

$dfs$,优化. $return$操作说明该操作完成之后的状态和经过操作$k$之后的状态是一样的.因此我们可以建树,然后从根节点开始$dfs$一次(回溯的时候复原一下状态)就可以算出所有状态的答案. 对于$1$和$2$操作,可以开一个数组$a[i][j]$记录每一格子被操作$1$和$2$操作了几次. 然后开一个数组$r[i]$记录每一行被操作$3$操作了几次. 每一个真正的状态为$\left( {a\left[ i \right]\left[ j \right] + r\left[ i \ri