您的位置:首页 > 其它

hdu 2829 Lawrence, hdu 3045 Picnic Cows,hdu 3480 Division , 斜率dp

2013-10-30 21:30 453 查看
斜率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]
);
}

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
);
}
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]
);
}

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: