The Bookcase

时间:2023-03-09 13:34:18
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 = ;
struct book{
int h,w;
}b[];
int dp[][],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=;i<=sum;++i)
for(int j=;j<=sum;++j)
dp[i][j]=INF;
dp[][]=;
int tw=;
for(int i=;i<n;++i){
for(int j=tw;j>=;--j)
for(int k=tw;k>=;--k){
if(dp[j][k]==INF||j+k>tw)continue;
int tmp=;
if(j==)
tmp=b[i].h;
dp[j+b[i].w][k]=min(dp[j+b[i].w][k],dp[j][k]+tmp);
tmp=;
if(k==)
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=;i<=sum;++i)
for(int j=;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[].h)*mw);
}
printf("%d\n",mina);
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
sum=;
for(int i=;i<n;++i){
scanf("%d%d",&b[i].h,&b[i].w);
sum+=b[i].w;
}
sort(b,b+n,cmp);
solve();
}
return ;
}