【类贪心+A little 模拟】 UPC~MAX 的读书计划

UPC2020年春混合个人训练4.26日场

题目描述
MAX 很喜欢读书,为了安排自己的读书计划,他会预先把要读的内容做好标记,A B 表示一个页段,即第 A 到 B 面,当然 A<B,若有两个页段 A-B,B-C,则可以直接记为 A-C,这样,他就可以一次看完,现在告诉你 n 个页段,请你帮他求出最长的一条页段,并输出这条页段的长度和组成它的页段个数。举个例子:
有 6 个页段:
2-7 1-3 3-12 12-20 7-10 4-50
那么连续的页段就有:
1-3,3-12,12-20 长度为 20-1+1=20 由 3 个页段组成
2-7,7-10 长度为 10-2+1=9 由 2 个页段组成
4-50 长度为 50-4+1=47 由 1 个页段组成
那么最长的一条就是第三个,所以结果为 47 1。
需要注意的是:如果有两条不一样的连续的页段长度同时为最大,那么取组成页段数多的一条.
例子: 1-5,5-10,1-10
输出: 10 2
输入
第一行为一个整数n,n<500;
第二行到第n+1行,每行两个整数A,B,记录一个页段的信息。0<=A<B<500
输出
输出一个整数,即最长的页段的长度和组成它的页段数。
样例输入
7
1 5
10 12
3 10
2 7
2 10
12 16
7 9
样例输出
15 3
提示
1-5 长度为5由1个页段组成
3-10,10-12,12-16 长度为14由3个页段组成
2-7,7-9 长度为8由2个页段组成
2-10,10-12,12-16 长度为15由3个页段组成

所以输出最长的页段的长度即15由3个页段组成

【数据规模】
对于30%的数据n<20,0<=A<B<500
对于100%的数据n<500,0<=A<B<500
解题思路:感觉这题没啥难想的地方,不过愣是卡了我一天,真是太菜了 用for遍历,每次寻找以第i个页段结尾的最长页段连续长度,前提是要把这n个页段存起来并按照每个页段的开始页数升序排列(这样是保证与第i个页段相连的页数较小的页段是在第i个的前面),额外注意要另开数组来存储以第i个页段结尾的最长页段连续长度和最大页段数,一开始存储的数据是不能动的,不然会导致找的过程中出错,还要注意题目中的要求,相同长度时取页段数多的,这个题差不多就解决了。
AC源:

#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 510;
int n;
int b[maxn],c[maxn];
struct node{
    int st,ed,num;  ///页段开始的页数,页段结束的页数,此页段的长度
}a[maxn];
bool cmp(node x,node y){
    if(x.st!=y.st) return x.st<y.st;
    else return x.ed<y.ed;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i].st,&a[i].ed);
        a[i].num=a[i].ed-a[i].st+1;

    }
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++) b[i]=a[i].num,c[i]=1;
    int max1=-1,max2=-1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<i;j++)
        {
            if(a[j].ed==a[i].st&&b[j]+a[i].num-1>=b[i])
            {
                b[i]=b[j]+a[i].num-1;
                c[i]=c[j]+1;
            }
        }
        max1=max(max1,b[i]); ///先挑选出页段长度最长的
    }
    for(int i=1;i<=n;i++)///找出相同长度时页段数更多的
    {
        if(max1==b[i]) max2=max(max2,c[i]);
    }
    for(int i=1;i<=n;i++)
    {
        if(b[i]==max1&&max2==c[i])
        {
            cout << b[i] << " " << c[i];
            break;
        }
    }
    return 0;
}

后半部分的代码有些冗杂,也挺方便理解的~~
星光不问赶路人,时光不负有心人~

猜你喜欢

转载自blog.csdn.net/zhazhaxiaosong/article/details/105825002