活动安排

描述 给定n个活动,每个活动安排的时间为[Ai, Bi]。求最多可以选择多少个活动,满足选择的活动时间两两之间没有重合。 输入描述: 第一行输入一个整数 1≤n≤100000 表示可选活动个数。 接下来的n行,每行输入两个整数Ai,Bi,0<= Ai<Bi<= 1000000000,表示第i个活动的时间。 输出描述: 输出一行一个整数,表示最多可选择的活动数,使用C语言实现

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    int start;
    int end;
} actv_t;

int cmpr(const void *a, const void *b)
{
    const actv_t *A = (const actv_t *)a;
    const actv_t *B = (const actv_t *)b;   
    if (A->end < B->end) return -1;
    if (A->end > B->end) return 1;
    return 0;
}

int main(void)
{
    int n;
    
    if (scanf("%d", &n) != 1 || n < 0) {
        printf("0\n");
        return 0;
    }
    
    if (n == 0) {
        printf("0\n");
        return 0;
    }

    // 使用动态内存分配
    actv_t *activities = (actv_t *)malloc(n * sizeof(actv_t));
    if (activities == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    for (int i = 0; i < n; i++) {
        if (scanf("%d %d", &activities[i].start, &activities[i].end) != 2) {
            printf("输入格式错误\n");
            free(activities);
            return 1;
        }
    }

    qsort(activities, n, sizeof(actv_t), cmpr);//入参需要特别注意,

    int count = 1;
    int last_end = activities[0].end;
    
    for (int i = 1; i < n; i++) {
        if (activities[i].start >= last_end) {
            count++;
            last_end = activities[i].end;
        }
    }
    
    printf("%d\n", count);
    
    free(activities);
    return 0;
}

全部评论

相关推荐

09-10 21:13
门头沟学院 Java
第一题:&nbsp;把数组排序后dp,dp[i]代表从1到i最多可以保留几个数。遍历数组,二分查找左边第一个差值大于d的数,假如二分出来下标为j,直接dp[i]&nbsp;=&nbsp;dp[j]&nbsp;+&nbsp;1。dp之后扫一遍dp数组取全局最大值,答案就是n减去这个全局最大值。注意如果删掉数量为奇数的话,答案得减一第二题:首先对于字符串第一个plog一定是不会被评论的,由此可得只要轮数足够多,所有与第一个plog不同的plog一定会被删除,所以把答案设置为第一个连续的字符的长度。通过观察可得,可以定义一个变量x,遇到一个不同于第一个plog的plog加一,遇到相同的话,如果x大于0就把x减一,否则就把答案减一。第三题:由题可得这是一棵树。如果x&gt;=y,显然可以一个一个节点炸,输出n*x就行。否则我们要让使用操作2的次数尽可能多。要让操作2尽可能多的话,就要通过使用操作一把连通块数量变得尽可能多。这可以用树上dp作。定义dp[u][0]为对该节点使用操作1,dp[u][1]是不使用,以u为根节点得到的子树内最大连通块的数量。对每个节点初始化&nbsp;dp[u][1]&nbsp;=&nbsp;1,&nbsp;dp[u][0]&nbsp;=&nbsp;0转移时通过dfs,对于所有子节点v,有:dp[u][0]&nbsp;&nbsp;=&nbsp;sum(max(dp[v][0]),&nbsp;dp[v][1]));dp[u][1]&nbsp;=&nbsp;sum(max(dp[v][0]),&nbsp;dp[v][1]&nbsp;-&nbsp;1));使用操作2最大次数就是max(dp[root][1],&nbsp;dp[root][0]),这个次数乘y加上剩余节点数乘x就是答案了
投递小红书等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务