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

探讨了如何通过贪心算法确定一个未知长度的整数序列的最短可能长度,该序列包含特定区间内的整数数量限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值