序列(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 10001
using 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;
}