【暑假】[深入动态规划]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<<"\n";
64    }
65    return 0;
66 }

 

你可能感兴趣的:(【暑假】[深入动态规划]UVa 10618 The Bookcase)