标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3507
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 9699 Accepted Submission(s): 3066
推荐博客:http://blog.csdn.net/azheng51714/article/details/8214165
1 //dp[i]=dp[j]+M+(sum[i]-sum[j])^2 2 //设k<j<i, j比k决策好 3 //dp[j]+M+(sum[i]-sum[j])^2<dp[k]+M+(sum[i]-sum[k])^2 4 //(dp[j]+num[j]^2-(dp[k]+num[k]^2))/(2*(num[j]-num[k]))<sum[i] 5 //dp[j]+num[j]^2-(dp[k]+num[k]^2)) GetUp() 6 //2*(num[j]-num[k]) GetDown() 7 #include <algorithm> 8 #include <iostream> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cstdio> 12 #include <vector> 13 #include <ctime> 14 #include <queue> 15 #include <list> 16 #include <set> 17 #include <map> 18 using namespace std; 19 #define INF 0x3f3f3f3f 20 typedef long long LL; 21 22 int dp[500010], n, m, sum[500010], q[500010]; 23 int GetDp(int i, int j) 24 { 25 return dp[j] + m + (sum[i]-sum[j])*(sum[i]-sum[j]); 26 } 27 int GetUp(int j, int k)//yj-yk的部分 28 { 29 return dp[j] + sum[j]*sum[j] - (dp[k]+sum[k]*sum[k]); 30 } 31 int GetDown(int j, int k)//xj-xk的部分 32 { 33 return 2 * (sum[j] - sum[k]); 34 } 35 int main() 36 { 37 while(~scanf("%d %d", &n, &m)) 38 { 39 sum[0] = dp[0] = 0; 40 for(int i = 1; i <= n; i++){ 41 scanf("%d", &sum[i]); 42 sum[i] += sum[i-1]; 43 } 44 int head = 0, tail = 0; 45 q[tail++] = 0; 46 for(int i = 1; i <=n; i++) 47 { 48 while(head+1<tail && GetUp(q[head+1],q[head])<=sum[i]*GetDown(q[head+1],q[head])) 49 head++; 50 dp[i] = GetDp(i, q[head]); 51 while(head+1<tail && GetUp(i, q[tail-1])*GetDown(q[tail-1],q[tail-2])<=GetUp(q[tail-1],q[tail-2])*GetDown(i,q[tail-1])) 52 tail--; 53 q[tail++] = i; 54 } 55 printf("%d\n", dp[n]); 56 } 57 return 0; 58 }
标签:
原文地址:http://www.cnblogs.com/luomi/p/5867993.html