标签:
4 1 4 5 1 2 4 2 4 5 1 2 0 0
17 2
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1010; 4 int sum[maxn],cost[maxn],q[maxn],dp[maxn][maxn],n,m; 5 bool check(int a,int b,int i,int j){ 6 int tmp = dp[a][j-1] - cost[a] + sum[a]*sum[a]; 7 tmp -= dp[b][j-1] - cost[b] + sum[b]*sum[b]; 8 return tmp > sum[i]*(sum[a] - sum[b]);//a 劣于 b 9 } 10 int up(int a,int b,int j){ 11 int y1 = dp[a][j-1] - cost[a] + sum[a]*sum[a]; 12 int y2 = dp[b][j-1] - cost[b] + sum[b]*sum[b]; 13 return y1 - y2; 14 } 15 int down(int a,int b){ 16 return sum[a] - sum[b]; 17 } 18 int main(){ 19 while(scanf("%d%d",&n,&m),n||m){ 20 sum[0] = cost[0] = 0; 21 for(int i = 1; i <= n; ++i){ 22 scanf("%d",sum + i); 23 cost[i] = cost[i-1] + sum[i-1]*sum[i]; 24 sum[i] += sum[i-1]; 25 dp[i][0] = cost[i]; 26 dp[i][i-1] = 0; 27 } 28 for(int j = 1; j <= m; ++j){ 29 int hd = 0,tl = 0; 30 q[tl++] = j; 31 for(int i = j + 1; i <= n; ++i){ 32 while(hd + 1 < tl && check(q[hd],q[hd+1],i,j)) ++hd; 33 dp[i][j] = dp[q[hd]][j-1] + cost[i] - cost[q[hd]] - sum[q[hd]]*(sum[i] - sum[q[hd]]); 34 while(hd + 1 < tl && up(q[tl-1],q[tl-2],j)*down(i,q[tl-1]) >= up(i,q[tl-1],j)*down(q[tl-1],q[tl-2])) --tl; 35 q[tl++] = i; 36 } 37 } 38 printf("%d\n",dp[n][m]); 39 } 40 return 0; 41 }
标签:
原文地址:http://www.cnblogs.com/crackpotisback/p/4809428.html