标签:思路 ems cst 接下来 表示 ++ problem efi 若是
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1299 Accepted Submission(s):
419
思路:尺取法,做法:例如下图所示,先把题设给出的那些区间预处理,合并有重叠的那些区间,处理后的区间互不重叠,区间编号可以从1开始计数,s为尺取法中取中的那些区间中最左边的那个区间的编号,t为最右边的区间的编号。若s的左端点直到t的右端点之间的空隙的和小于等于补签卡的个数,此时更新所求区间的最大长度,并且补签卡没用完,说明t点也许还可以往右延伸,以获得更大的区间长度,直到t尝试走完所有区间;若s,t之间的空隙的和大于补签卡个数,说明t走得太过远了,换句话说,若是以s为签到的第一个区间,用完m张签到卡,最多也只能走到(t-1)区间的后面一点点,不会到达t区间的左端点,此时也要更新区间的最大长度,并且让s往右挪一区间。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<stdio.h> #include<algorithm> #include<queue> #include<set> #include<vector> #include<cstring> #include<string> #include<cmath> using namespace std; typedef long long ll; const int N_MAX = 100000+5; struct Interval { int Left, Right; Interval(int Left=0,int Right=0):Left(Left),Right(Right) {} bool operator <(const Interval&b) const{ if (this->Left != b.Left)return this->Left < b.Left; else return this->Right < b.Right; } }interval[N_MAX]; vector<Interval>vec; int n, m; ll c[N_MAX];//c[j]记录到区间j为止(包括j)的所有区间和,不包含中间的空隙 int main() { while (scanf("%d%d", &n, &m) != EOF) { vec.clear(); memset(c, 0, sizeof(c)); for (int i = 0; i < n; i++) { scanf("%d%d", &interval[i].Left, &interval[i].Right); } sort(interval, interval + n); vec.push_back(interval[0]); for (int i = 1; i < n; i++) {//合并所有可以合并的区间 Interval P = vec[vec.size() - 1]; if (interval[i].Left <= P.Right + 1) {//两个区间可以合并 int Left, Right; Right = max(P.Right, interval[i].Right); vec.pop_back(); Left = P.Left; vec.push_back(Interval(Left, Right)); } else { vec.push_back(interval[i]); } } int N = vec.size();//区间的数量 for (int i = 1; i <= N;i++) {//c[i],第i个区间为止所有区间的大小的和 c[i] += c[i-1] + vec[i-1].Right - vec[i-1].Left + 1; } int s = 1, t = 1; ll res = 0; ll num; for (;;) { while (t <= N&&(num=(vec[t-1].Right-vec[s-1].Left+1-(c[t]-c[s-1])) )<= m) { ll diff = vec[t - 1].Right - vec[s - 1].Left + 1; res =max(res,diff); t++; } if (num <= m) { break; } ll remain = c[t-1]-c[s-1]+m ; res = max(res, remain); s++; } res = max(res, c[N ] - c[s - 1] + m); printf("%lld\n", res); } return 0; }
标签:思路 ems cst 接下来 表示 ++ problem efi 若是
原文地址:http://www.cnblogs.com/ZefengYao/p/7359980.html