题解 P1645 【序列】

顾z

2018-06-28 06:53:07

Solution

"~~序列是不连续的~~" “~~你们应该知道~~” 思想:sort排序:以左端点为第一关键字排序,右端点为第二关键字排序。 区间覆盖问题 做法: 每次选取左端点最大的进行贪心。 枚举这一段区间时,从左到右选取 尽可能靠左的整数点。 这时候要判断是否被标记过。 如果被标记过,该区间中的C(同题目)--。 再次遍历这段区间,要判断此时的C是否<=0. 如果<=0则要break; 如果存在C,则继续标记较靠左的整数点。 CODE如下: ~~貌似可以改一下 大佬手轻点~~ ~~蒟蒻第一篇题解~~ ```cpp #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<map> #include<queue> #include<vector> #define ll long long #define ull unsigned long long #define inf 2147483647 using namespace std; int N,L,R,C,minl=9999,maxr,ans;bool NOW[20000]; struct code{ int l,r,c; }op[20000]; bool read(int &x){ int f=1;x=0;char s=getchar(); while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();} while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();} x*=f; } void print(int x){ if(x<0){ putchar('-'); x=-x; } if(x>9) print(x/10); putchar(x%10+'0'); } bool ccp(const code &a,const code &b) { if(a.l!=b.l)return a.l<b.l; else return a.r>b.r; } int main() { read(N); for(int i=1;i<=N;i++) { read(op[i].l),read(op[i].r),read(op[i].c); minl=min(minl,op[i].l),maxr=max(op[i].r,maxr); } sort(op+1,op+N+1,ccp); for(int i=N;i>=1;--i) { int couldget=op[i].c; for(int k=op[i].l;k<=op[i].r;k++)if(NOW[k])couldget--; for(int j=op[i].l;j<=op[i].c+op[i].l &&j<=op[i].r;j++) { if(couldget<=0)break; else if(!NOW[j]){ couldget--; NOW[j]=1; } } } for(int i=minl;i<=maxr;i++) if(NOW[i])ans++; print(ans); } ```