记录编号 249177 评测结果 AAAAAAAAAA
题目名称 [SDOI 2016 Round1] 征途 最终得分 100
用户昵称 Gravatar_Horizon 是否通过 通过
代码语言 C++ 运行时间 1.275 s
提交时间 2016-04-12 11:36:07 内存使用 69.48 MiB
显示代码纯文本
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cmath>
  6. #define maxn 3010
  7. using namespace std;
  8.  
  9. int n, m, a[maxn];
  10.  
  11. long long dp[maxn][maxn];
  12. long long s[maxn];
  13.  
  14. int que[maxn], head, tail;
  15.  
  16. #define sqr(x) (x) * (x)
  17.  
  18. long double getK(int j, int k, int tp){
  19. return (long double)(dp[tp][k] - dp[tp][j] + sqr(s[k]) - sqr(s[j])) / 2.0 / (s[k] - s[j]);
  20. }
  21.  
  22. void trans(int j){
  23. head = tail = 1;
  24. que[1] = 0;
  25. for(int i = 1; i <= n; i ++){
  26. while(head < tail && s[i] >= getK(que[head], que[head+1], j-1))
  27. head ++;
  28. dp[j][i] = dp[j-1][que[head]] + sqr(s[i] - s[que[head]]);
  29. while(head < tail && getK(que[tail-1], que[tail], j-1) > getK(que[tail], i, j-1))
  30. tail --;
  31. que[++ tail] = i;
  32. }
  33. }
  34.  
  35. int main(){
  36. freopen("menci_journey.in", "r", stdin);
  37. freopen("menci_journey.out", "w", stdout);
  38. scanf("%d%d", &n, &m);
  39. memset(dp, 0x7f, sizeof dp);
  40. dp[0][0] = 0;
  41. for(int i = 1; i <= n; i ++)
  42. scanf("%d", &a[i]), s[i] = s[i-1] + a[i];
  43. for(int j = 1; j <= m; j ++)
  44. trans(j);
  45. printf("%lld\n", dp[m][n] * m - sqr(s[n]));
  46. return 0;
  47. }