zoukankan      html  css  js  c++  java
  • 【暑假】[深入动态规划]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本书第二层宽度为j第三层宽度为k时二三层的最小的高度和。

      状态转移方程:(->表示更新)

         d[i][j][k]->d[i+1][j][k]

         d[i][j][k]+f(j,book[i].h)->d[i+1][j+book[i].w][k]

         d[i][j][k]+f(k,book[i].h->d[i+1][j][k+book[i].w]

      定义f(a,b):当a==0时return b esle return 0; 关于第一层,高度为book[0].h宽度为pre_w[n]-ww2-ww3;

     

    优化: 

    1.   时间:考虑到第i本书时, j+k不超过前i本书的宽度之和,减小jk的枚举范围。
    2.   时间:书上这样说:如果ww2>ww1+30 那么可以把第2层的一本书放到第1层情况不会更差,所以只需要计算ww2<=ww1+30 且ww3<=ww2+30情况。此时有j<=1065 k<=720。
    3.   空间:滚动数组,细节不好判断因此同时保留两行,操作行与更新行。

    代码:

     1 #include<iostream>
     2 #include<algorithm>
     3 #define FOR(a,b,c) for(int a=(b);a<=(c);a++) 
     4 using namespace std;
     5 
     6 const int maxn = 70 + 5;
     7 const int maxw = 30;
     8 const int INF = 1<<30;
     9 
    10 struct Node{
    11     int w,h;
    12     bool operator <(const Node& rhs) const { 
    13       return h>rhs.h || (h==rhs.h && w>rhs.w);
    14     }
    15 }book[maxn];
    16 
    17 int d[2][maxn*maxw][maxn*maxw];
    18 int pre_w[maxn];
    19 
    20 int n;
    21 
    22 inline int f(int j,int h) {
    23     return j==0? h:0;   
    24 }
    25 inline void update(int& x,int v) {
    26     if(x<0 || v<x) x=v;
    27 } 
    28 
    29 int main() {
    30 ios::sync_with_stdio(false); 
    31    
    32    int T;  cin>>T;
    33    while(T--) {
    34          cin>>n;
    35          FOR(i,0,n-1) cin>>book[i].h>>book[i].w;
    36          sort(book,book+n);     
    37          pre_w[0]=0;
    38          FOR(i,1,n) pre_w[i]=pre_w[i-1]+book[i-1].w;
    39          
    40          d[0][0][0]=0;
    41          int t=0;
    42          FOR(i,0,n-1) {
    43              FOR(j,0,pre_w[i+1])
    44               FOR(k,0,pre_w[i+1]-j) d[t^1][j][k]=-1;   
    45               
    46            FOR(j,0,pre_w[i]) 
    47               FOR(k,0,pre_w[i]-j) if(d[t][j][k]>=0){ 
    48                   update(d[t^1][j][k],d[t][j][k]);
    49                   update(d[t^1][j+book[i].w][k],d[t][j][k]+f(j,book[i].h));
    50                   update(d[t^1][j][k+book[i].w],d[t][j][k]+f(k,book[i].h));
    51               }
    52           t^=1;  
    53      }
    54            
    55              
    56              int ans=INF;
    57              FOR(j,1,pre_w[n])
    58               FOR(k,1,pre_w[n]-j) if(d[t][j][k]>=0){
    59                   int w=max(max(j,k),pre_w[n]-j-k);
    60             int h=d[t][j][k]+book[0].h;  
    61             ans=min(ans,w*h);
    62               }
    63              cout<<ans<<"
    ";
    64    }
    65    return 0;
    66 }
  • 相关阅读:
    ISO14229:2013 之 通过标志输入输出控制InputOutputControlByIdentifier (0x2F)
    ISO14229:2013 之 清除诊断信息ClearDiagnosticInformation (0x14)
    ISO14229:2013 之 通过标志写数据WriteDataByIdentifier (0x2E)
    Git常用命令及方法大全
    High concurrency Architecture Detailed _ Architecture
    Data structures and algorithms in Java, Part 1: Overview
    Java代码优化
    详解二分查找算法
    服务容灾
    分布式限流之一:redis+lua 实现分布式令牌桶,高并发限流
  • 原文地址:https://www.cnblogs.com/lidaxin/p/4743024.html
Copyright © 2011-2022 走看看