[关闭]
@ZCDHJ 2018-09-19T07:01:49.000000Z 字数 892 阅读 424

ZJOI2005 午餐

动态规划


Luogu

显然每个队列按吃饭时间降序排列最优

那么就可以 dp 了

为前 个人,第一个队列打饭时间为 ,第二个队列为 。因为 是个定值,所以可以压成两维。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. const int INF = 0x3f3f3f3f;
  6. const int MAXN = 200 + 5;
  7. int N, Ans = INF;
  8. int Dp[MAXN][MAXN * 200], Sum[MAXN];
  9. struct Node
  10. {
  11. int a, b;
  12. } A[MAXN];
  13. inline int read()
  14. {
  15. register int x = 0;
  16. register char ch = getchar();
  17. while(!isdigit(ch)) ch = getchar();
  18. while(isdigit(ch))
  19. {
  20. x = x * 10 + ch - '0';
  21. ch = getchar();
  22. }
  23. return x;
  24. }
  25. bool comp(Node x, Node y)
  26. {
  27. return x.b > y.b;
  28. }
  29. int main()
  30. {
  31. N = read();
  32. for(int i = 1; i <= N; ++i)
  33. {
  34. A[i].a = read();
  35. A[i].b = read();
  36. }
  37. std::sort(A + 1, A + 1 + N, comp);
  38. for(int i = 1; i <= N; ++i) Sum[i] = Sum[i - 1] + A[i].a;
  39. memset(Dp, INF, sizeof(Dp));
  40. Dp[0][0] = 0;
  41. for(int i = 1; i <= N; ++i)
  42. {
  43. for(int j = 0; j <= Sum[i]; ++j)
  44. {
  45. if(j >= A[i].a) Dp[i][j] = std::max(Dp[i - 1][j - A[i].a], j + A[i].b);
  46. Dp[i][j] = std::min(Dp[i][j], std::max(Dp[i - 1][j], Sum[i] - j + A[i].b));
  47. }
  48. }
  49. for(int i = 0; i <= Sum[N]; ++i) Ans = std::min(Ans, Dp[N][i]);
  50. printf("%d\n", Ans);
  51. return 0;
  52. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注