SDUT 2412 (单调队列 + dp)

  http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2412

  实验证明,被小错误搞死的感觉太不爽了!!

  这题是去年省赛的题,今天重新做了一下。我了个去。被俩二b错误搞死了。!!

  思路:先预处理出某一秒如果切的话能得到的最大值。然后单调队列优化一下就行。

  

View Code
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))
#define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define Read()  freopen("data.in", "r", stdin)
#define Write() freopen("data.out", "w", stdout);

typedef long long LL;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int inf = ~0u>>2;

using namespace std;

const int N = 10010;

struct node {
    int t, p;
    bool s;
    bool operator < (const node b) const {
        if(t == b.t)    return p < b.p;
        else    return t < b.t;
    }
} pt[N];

int dp[N];
int val[N];
int tim[N];
int vt[N];   //二b错误1:内存开小了
int n, m, tt;

int q[N];

int main() {
    //Read();

    int T, i, x, con;
    int l, r, j, cas = 0;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &n, &m);
        for(i = 1; i <= n; ++i) {
            scanf("%d%d%d", &pt[i].t, &x, &pt[i].p);
            if(x)   pt[i].s = true;
            else    pt[i].s = false;
        }
        sort(pt + 1, pt + n + 1);    //二b错误2:从0...n排序
        tt = 0;
        CL(val, 0);
        for(i = 1; i <= n; ) {
            l = i; r = l;
            while(pt[l].t == pt[r].t && r <= n) ++r;

            int mx = 0;
            //max sum of segment
            con = 0; vt[l-1] = 0;
            for(j = l; j < r; ++j) {
                if(pt[j].s == false) {
                    con++;
                    vt[j] = max(vt[j-con] + (con >= 3 ? con*2 : con), (con >= 3 ? con*2 : con));
                } else {
                    con = 0;
                    vt[j] = vt[j-1] - 1;
                }
                mx = max(mx, vt[j]);
            }
            i = r;
            val[pt[l].t] = mx;
            tt = max(tt, pt[l].t);
            //printf("%d %d\n", pt[l].t, mx);
        }
        int head = 0, tail = 0;
        CL(dp, 0);

        for(i = 0; i <= m + 1; ++i) dp[i] = val[i];
        for( ; i <= tt; ++i) {
            while(head < tail && dp[q[tail-1]] < dp[i-m-1])    tail--;
            q[tail++] = i - m - 1;
            dp[i] = dp[q[head]] + val[i];
        }

        int ans = 0;
        for(i = 0; i <= tt; ++i) {
            ans = max(ans, dp[i]);
        }

        printf("Case %d: %d\n", ++cas, ans);
    }
    return 0;
}

 

你可能感兴趣的:(SDUT 2412 (单调队列 + dp))