[关闭]
@Acqua 2019-01-20T01:53:40.000000Z 字数 1087 阅读 996

CF294B Shaass and Bookshelf(Jan. 18th, 2019) 创造性

动态规划

题目来源

题意

想以优雅强迫症的方式放置本厚度的书籍,书籍宽度不一定相等,但高度一致。放不下的书可以放在所有书的顶上,但是要保证顶上的书的总宽度不超过书架宽度。求能放下书[1])的最小书架宽度。

思路

表示放第本书时,厚度总和为,宽度总和为时的情况是否成立。


滚动数组压掉维,维边界为200,因为书籍总厚度最大为200,故答案只可能在这个区间内(易证不会有超出200的答案)。

反思

  1. 很多题都很显然,只是需要去仔细推算。

代码

  1. // La Pluie
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. using namespace std;
  7. const int N = 100 + 5;
  8. int dp[N][N << 1][N << 1], t[N], w[N];
  9. int main(){
  10. int n;
  11. scanf("%d", &n);
  12. int T = 0, W = 0;
  13. for(int i = 1; i <= n; i++){
  14. scanf("%d %d", &t[i], &w[i]);
  15. T += t[i]; W += w[i];
  16. }
  17. dp[0][0][0] = 1;
  18. for(int i = 1; i <= n; i++){
  19. for(int j = 0; j <= T; j++){
  20. for(int k = 0; k <= min(W, 200); k++){
  21. if(j >= t[i]) dp[i][j][k] |= dp[i - 1][j - t[i]][k];
  22. if(k >= w[i]) dp[i][j][k] |= dp[i - 1][j][k - w[i]];
  23. }
  24. }
  25. }
  26. int ans = 200;
  27. for(int i = 1; i <= n; i++){
  28. for(int j = 0; j <= T; j++){
  29. for(int k = 0; k <= min(W, 200); k++){
  30. if(k > j) break;
  31. if(dp[n][j][k]) ans = min(ans, max(j, k));
  32. }
  33. }
  34. }
  35. printf("%d", ans);
  36. return 0;
  37. }

[1] 竖直放置书籍的水平放置书籍的目标书架宽度。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注