1 条题解
-
0
自动搬运
来自洛谷,原作者为

81179332_
这个家伙很菜,什么也没有留下搬运于
2025-08-24 21:34:38,当前版本为作者最后更新于2020-06-24 16:00:10,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
设 表示放了前 本书,第一层厚度为 ,第二层厚度为 ,第三层厚度为 的最小高度和
容易想到,我们将所有书按照高度从大到小排序,那么每一层的高度就是第一个放入该层的书的高度
记 显然,,则 ,由此,我们可以省掉 这一维
再加一个滚动数组优化就可以啦
转移方程较为简单,见代码,采用刷表法比较好写
//timeuse:20min const int N = 80,M = 2110; int n; struct book { int h,t; }a[N]; int f[2][M][M],sum[N]; void minn(int &a,int b) { if(a > b) a = b; } int main() { freopen("random.in","r",stdin); freopen("sol.out","w",stdout); n = read();for(int i = 1;i <= n;i++) a[i].h = read(),a[i].t = read(); sort(a + 1,a + 1 + n,[&](book u,book v) { return u.h > v.h; }); for(int i = 1;i <= n;i++) sum[i] = sum[i - 1] + a[i].t; memset(f[0],63,sizeof(f));f[0][0][0] = 0; for(int i = 1;i <= n;i++) { int now = i & 1,pre = now ^ 1; memset(f[now],63,sizeof(f[now])); for(int j = 0;j <= sum[i - 1];j++) for(int k = 0;k <= sum[i - 1];k++) { if(j == 0) minn(f[now][j + a[i].t][k],f[pre][j][k] + a[i].h); else minn(f[now][j + a[i].t][k],f[pre][j][k]); if(k == 0) minn(f[now][j][k + a[i].t],f[pre][j][k] + a[i].h); else minn(f[now][j][k + a[i].t],f[pre][j][k]); if(sum[i - 1] - j - k == 0) minn(f[now][j][k],f[pre][j][k] + a[i].h); else minn(f[now][j][k],f[pre][j][k]); } }ll ans = LINF; for(int i = 1;i <= sum[n];i++) for(int j = 1;j <= sum[n];j++) if(sum[n] - i - j > 0) ans = min(ans,(ll)max(max(i,j),sum[n] - i - j) * f[n & 1][i][j]); fprint(ans); return 0; }
- 1
信息
- ID
- 1163
- 时间
- 5000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者