题目:http://acm.hdu.edu.cn/showproblem.php?pid=3045
View Code
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #define ll __int64 #define clr(a,b) memset(a, b, sizeof(a)) using namespace std; const int N = 500000+10; const int M = 10000+10; const int inf = 0x3f3f3f3f; int m, n, l, r; int q[N]; ll a[N], s[N], dp[N]; // dp[i] = min{dp[j]+sum[i]-sum[j]-(i-j)*a[j+1]} void input() { for (int i=1; i<=n; i++) scanf("%I64d", &a[i]); sort(a+1, a+n+1); a[0] = s[0] = dp[0] = 0; for (int i=1; i<=n; i++) s[i] = s[i-1] + a[i], dp[i] = 0; } bool super1(int k1, int k2, int k3, int i) { return (dp[k3]-dp[k2]-(i-k3)*a[k3+1]+(i-k2)*a[k2+1])*(s[k2]-s[k1]) <=(dp[k2]-dp[k1]-(i-k2)*a[k2+1]+(i-k1)*a[k1+1])*(s[k3]-s[k2]); // =很重要,,poj3709上没有这个WA了 } bool super2(int k1, int k2, int i) { return dp[k1]-s[k1]-(i-k1)*a[k1+1]>=dp[k2]-s[k2]-(i-k2)*a[k2+1]; } int main() { //freopen("D:/a.txt", "r", stdin); while (~scanf("%d%d", &n, &m)) { input(); q[l=0] = 0, r=-1; for (int i=1; i<=n; i++) { if (i>=2*m) { int now = i-m; while (l<r && super1(q[r-1],q[r],now,i))r--; q[++r]=now; } while (l<r && super2(q[l],q[l+1],i))l++; int k = q[l]; dp[i] = dp[k]+s[i]-s[k]-(i-k)*(a[k+1]); } printf("%I64d\n", dp[n]); } return 0; }