您的位置:首页 > 其它

UVA12099 The Bookcase

2017-10-25 20:55 513 查看
The Bookcase
https://odzkskevi.qnssl.com/31465a17250189570dad37924cda0d26?v=1508622471
【题解】

。。。紫书上第二个优化不可信啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

去了第二个优化写的滚动数组!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

各种智障错!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

调了少说五六个小时!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

气啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

这里规定第一层高度 >= 第二层高度 >= 第三层高度

不难发现交换任意两层是一样的,所以这样规定无可厚非

dp状态和转移见程序

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))

inline void swap(int &a, int  &b)
{
long long tmp = a;a = b;b = tmp;
}

inline void read(int& x)
{
x = 0;char ch = getchar(), c = ch;
while(ch < '0' || ch > '9')c = ch, ch = getchar();
while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
}

const int INF = 0x3f3f3f3f;
const int MAXN = 80;
const int MAXJ = 2500;
const int MAXK = 2500;

int dp[2][MAXK + 10][MAXK + 10], n, sum[MAXN + 10], t, ans;

struct Node
{
int h,w;
}node[MAXN + 10];

int cmp(Node a, Node b)
{
return a.h == b.h ? a.w < b.w : a.h > b.h;
}

int main()
{
read(t);
for(;t;--t)
{
read(n);
ans = INF;
for(register int i = 1;i <= n;++ i) read(node[i].h), read(node[i].w);
std::sort(node + 1, node + 1 + n, cmp);
for(register int i = 1;i <= n;++ i)sum[i] = sum[i - 1] + node[i].w;
//dp[i][j][k]表示前i本书,第二层宽j,第三层宽k,第一层宽sum[i] - j - k,高度h1 <= h2 <= h3的最小总高度
dp[0][0][0] = 0;
memset(dp[1], 0x3f, sizeof(dp[1]));
dp[1][0][0] = node[1].h;
int now = 1;
for(register int i = 1;i < n;++ i)
{
memset(dp[now ^ 1], 0x3f, sizeof(dp[now ^ 1]));
for(register int j = 0;j <= sum
;++ j)
{
if(j > sum[i + 1] - sum[1])break;
for(register int k = 0;k <= sum
;++ k)
{
if(j + k > sum[i + 1] - sum[1])break;
//放在第一层
dp[now ^ 1][j][k] = min(dp[now ^ 1][j][k], dp[now][j][k]);
//放在第二层
if(j + node[i + 1].w <= sum[i + 1])
{
if(j == 0) dp[now ^ 1][j + node[i + 1].w][k] = min(dp[now ^ 1][j + node[i + 1].w][k], dp[now][j][k] + node[i + 1].h);
else dp[now ^ 1][j + node[i + 1].w][k] = min(dp[now ^ 1][j + node[i + 1].w][k], dp[now][j][k]);
}
//放在第三层
if(k + node[i + 1].w <= sum[i + 1] && j != 0)
{
if(k == 0) dp[now ^ 1][j][k + node[i + 1].w] = min(dp[now ^ 1][j][k + node[i + 1].w], dp[now][j][k] + node[i + 1].h);
else dp[now ^ 1][j][k + node[i + 1].w] = min(dp[now ^ 1][j][k + node[i + 1].w], dp[now][j][k]);
}
}
}
now ^= 1;
}
for(register int j = 1;j <= sum
;++ j)
for(register int k = 1;k <= sum
;++ k)
{
if(dp[now][j][k] >= INF)continue;
if(sum
- j - k < node[1].w)break;
ans =  min(ans, dp[now][j][k] * max(j, max(k, sum
- j - k)));
}
printf("%d\n", ans);
}
return 0;
}


UVA12099
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: