序列(rms模拟7-1)* *(贪心)

来源:互联网 发布:制造业 数据分析部门 编辑:程序博客网 时间:2024/05/16 09:54

序列(sequence.cpp)**
试题描述
有一个整数序列,它的每个数各不相同,我们不知道它的长度是多少(即整数个数),
但我们知道在某些区间中至少有多少个整数,用区间(Li,Ri,Ci)来描述,表示这个整数序列
中至少有 Ci 个数来自区间[Li,Ri],给出若干个这样的区间,问这个整数序列的长度最少能
为多少?
输入格式:
第一行一个整数N,表示区间个数;
接下来N行,每行三个整数(Li,Ri,Ci),描述一个区间。
输出格式:
仅一个数,表示该整数序列的最小长度。
输入样例:
4
4 5 1
6 10 3
7 10 3
5 6 1
输出样例:
4
数据规模:
N<=1000,0<=Li<=Ri<=1000,1<=Ci<=Ri - Li + 1

题解
可以将所有的区间按照右端点从小到大排序来考虑问题。对于当前的区间假设满足了它的要求,即这个区间中至少有Ci 个数,那么怎么安排这些数的位置是无所谓的;又因为之后的区间都是右端点在当前这个区间右端点的右边区间,故贪心地选当前区间靠后的若干个数。这样不但可以满足当前区间的要求,还可以尽量满足后面区间的要求,并且这种贪心的方法是最优的。

代码

#include<bits/stdc++.h>#define F( i,a,b ) for( int i=(a);i<=(b);i++ )#define F_2( i,a,b ) for( int i=(a);i>=(b);i-- )#define oo 0x7fffffff#define LL long long#define N 1001#define M 10001using namespace std;int read(){    int f=1,s=0;    char ch=getchar();    while( ch<'0' || ch>'9' ){ if( ch=='-' ) f=-1;ch=getchar(); }    while( ch>='0' && ch<='9' ){ s=( s<<1 )+( s<<3 )+ch-'0';ch=getchar(); }    return f*s;}int m,n;int ans,cnt,tot;struct node{    int l,r,c;}a[N];int used[N];bool my_cmp( const node &a,const node &b ){    return a.r<b.r;}int main(){    n=read();    F( i,1,n )    {        a[i].l=read();        a[i].r=read();        a[i].c=read();    }    sort( a+1,a+n+1,my_cmp );    F( i,1,n )    {        cnt=0;        F( j,a[i].l,a[i].r )        {            if( used[j] )                cnt++;        }        F_2( j,a[i].r,a[i].l )        {            if( cnt>=a[i].c )                break;            if( !used[j] )            {                used[j]=1;                cnt++;            }        }       }    F( i,1,a[n].r )         if( used[i] )            ans++;    cout<<ans<<endl;    return 0;}
原创粉丝点击