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