斜率dp的几题.
hdu2829
//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FF(i, a, b) for(int i = (a); i < (b); ++i)
#define FD(i, b, a) for(int i = (b) - 1; i >= (a); --i)
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FED(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)
#define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)
#define RS(s) scanf("%s", s)
//OUTPUT
#define WI(n) printf("%d\n", n)
#define WS(s) printf("%s\n", s)
typedef long long LL;
typedef vector <int> VI;
const int INF = 1000000000;
const double eps = 1e-10;
const int MAXN = 1005;
int n, m;
int s[MAXN];
int a[MAXN];
int tol;
int q[MAXN], be, ed;
int dp[MAXN][MAXN];
int getUp(int i, int j, int k)
{
// return -1 * dp[k - 1][j] + s[j] * s[j] - (-1 * dp[k - 1][i] + s[i] * s[i]);
return s[j] * s[j] - dp[k - 1][j] - (s[i] * s[i] - dp[k - 1][i]);
}
int getDown(int i, int j)
{
return s[j] - s[i];
}
void solve()
{
FE(i, 1, m)
{
be = 1;
ed = 0;
q[++ed] = i;
FE(j, i + 1, n)
{
while (be < ed)
{
int p1= q[be];
int p2 = q[be + 1];
int x1 = getDown(p1, p2);
int y1 = getUp(p1, p2, i);
if (y1 <= s[j] * x1) be++;
else break;
}
int p = q[be];
dp[i][j] = dp[i - 1][p] + s[p] * (s[j] - s[p]);
while(be < ed)
{
int p1 = q[ed - 1];
int p2 = q[ed];
int x1 = getDown(p1, p2);
int x2 = getDown(p2, j);
int y1 = getUp(p1, p2, i);
int y2 = getUp(p2, j, i);
if (y1 * x2 >= y2 * x1) ed--;
else break;
}
q[++ed] = j;
}
}
printf("%d\n", tol - dp[m][n]);
}
int main ()
{
while (~RII(n, m) && (n || m))
{
s[0] = 0;
FE(i, 1, n)
{
RI(a[i]);
s[i] = s[i - 1] + a[i];
}
tol = 0;
FED(i, n, 2)
{
tol += a[i] * s[i - 1];
}
CLR(dp, 0);
solve();
}
return 0;
}
hdu3045
//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FF(i, a, b) for(int i = (a); i < (b); ++i)
#define FD(i, b, a) for(int i = (b) - 1; i >= (a); --i)
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FED(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)
#define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)
#define RS(s) scanf("%s", s)
//OUTPUT
#define WI(n) printf("%d\n", n)
#define WS(s) printf("%s\n", s)
typedef long long LL;
typedef vector <int> VI;
const int INF = 1000000000;
const double eps = 1e-10;
const int MAXN = 400005;
int q[MAXN];
LL dp[MAXN];
LL a[MAXN], s[MAXN];
int be, ed;
int n, k;
LL getUp(int i, int j)
{
return dp[j] - s[j] + j * a[j + 1] - (dp[i] - s[i] + i * a[i + 1]);
}
LL getDown(int i, int j)
{
return a[j + 1] - a[i + 1];
}
void solve()
{
CLR(dp, 0);///
be = 1;
ed = 0;
q[++ed] = 0;
FE(i, k, n)///
{
while (be < ed)
{
int p1 = q[be];
int p2 = q[be + 1];
LL x1 = getDown(p1, p2);
LL y1 = getUp(p1, p2);
if (y1 <= i * x1) be++;
else break;
}
int p = q[be];
dp[i] = dp[p] + s[i] - s[p] - (i - p) * a[p + 1];
int j = i - k + 1;
if (j < k) continue;///!!!!!!!!!!!!!!!!!!!!!!!!!
while (be < ed)
{
int p1 = q[ed - 1];
int p2 = q[ed];
LL x1 = getDown(p1, p2);
LL x2 = getDown(p2, j);
LL y1 = getUp(p1, p2);
LL y2 = getUp(p2, j);
if (y1 * x2 >= y2 * x1) ed--;
else break;
}
q[++ed] = j;
}
printf("%I64d\n", dp[n]);
}
int main ()
{
while (~RII(n, k))
{
FE(i, 1, n) scanf("%I64d", &a[i]);
sort(a + 1, a + 1 + n);
s[0] = 0;
FE(i, 1, n) s[i] = s[i - 1] + a[i];
solve();
}
return 0;
}
hdu3480
//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FF(i, a, b) for(int i = (a); i < (b); ++i)
#define FD(i, b, a) for(int i = (b) - 1; i >= (a); --i)
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FED(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
#define CPY(a, b) memcpy(a, b, sizeof(a))
#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
//STL
#define SZ(V) (int)V.size()
#define PB push_back
#define EQ(a, b) (fabs((a) - (b)) <= 1e-10)
#define ALL(c) (c).begin(), (c).end()
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)
#define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)
#define RS(s) scanf("%s", s)
//OUTPUT
#define WI(n) printf("%d\n", n)
#define WS(s) printf("%s\n", s)
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> VI;
const int INF = 1000000000;
const double eps = 1e-10;
const int MAXN = 10005;
int q[MAXN], be, ed;
int a[MAXN];
int dp[5005][MAXN];
int n, m;
int getUp(int i, int j, int k)
{
return dp[k - 1][j] - dp[k - 1][i] + a[j + 1] * a[j + 1] - a[i + 1] * a[i + 1];
}
int getDown(int i, int j)
{
return a[j + 1] - a[i + 1];
}
int solve()
{
FE(i, 1, n)
dp[1][i] = (a[i] - a[1]) * (a[i] - a[1]);
FE(i, 2, m)
{
be = 1;
ed = 0;
q[++ed] = i - 1;
FE(j, i, n)
{
while (be < ed)
{
int p1 = q[be];
int p2 = q[be + 1];
int x1 = getDown(p1, p2);
int y1 = getUp(p1, p2, i);
if (y1 <= 2 * a[j] * x1) be++;
else break;
}
int p = q[be];
dp[i][j] = dp[i - 1][p] + (a[j] - a[p + 1]) * (a[j] - a[p + 1]);
while (be < ed)
{
int p1 = q[ed - 1];
int p2 = q[ed];
int p3 = j;
int x1 = getDown(p1, p2);
int x2 = getDown(p2, p3);
int y1 = getUp(p1, p2, i);
int y2 = getUp(p2, p3, i);
if (x1 * y2 <= x2 * y1) ed--;
else break;
}
q[++ed] = j;
}
}
printf("%d\n", dp[m][n]);
}
int main ()
{
int T;
RI(T);
int iCase = 1;
while (T--)
{
RII(n, m);
// a[0] = 0;
FE(i, 1, n)
RI(a[i]);
sort(a + 1, a + 1 + n);
// CLR(dp, 0);
printf("Case %d: ",iCase++);
solve();
}
return 0;
}