洛谷 USACO P2207 Photo

670 2025-06-01 05:34:08

题目描述

Framer Jhon 打算给他的N头奶牛照相,( 2 <= N <= 1 000 000 000) 。

他们排成一条线,并且依次取1~N作为编号。

每一张照片可以拍摄到这列奶牛中一个连续的区间中的奶牛。

对于每一头奶牛,FJ都想要让Ta至少出现在一张照片里。

不幸的是,有K对关系不好的奶牛( 1 <= K <= 1000),他们拒绝出现在同一张照片里。

已知所有关系不好的奶牛所在的位置,请计算出FJ需要的最小需要拍摄的照片数量。

输入输出格式

输入格式:

*第一行: 两个整数: N,K.

*第2..K+1行中,第i+1行有两个整数,记为A_i与B_i。它们代表着处在队列中第A_i头奶牛与第B_i头奶牛是关系不好的,它们不能出现在同一张照片里。

输出格式:

*一个整数,代表FJ需要的最小需要拍摄的照片数量

输入输出样例

输入样例#1:

7 3

1 3

2 4

5 6

输出样例#1:

3

说明

输出解释:FJ可以只拍三张照片:[1,2] , [3,5] , [6,7]

网上找不到题解的任何行踪。。

A了这道题之后看了看洛谷上其他提交的代码 都没有我的好

我的代码也不一定完全对,有一些贪心的成分在里面

大概说一下:

每一对无法共存的关系储存在结构体num里,较小的为a,较大的为b。这个问题就转换成了求最少区间不包含任何一个完整的num区间。

我们按照较小的a对num进行排序。

我们逐个扫描每个num,记录当前所在分组的区间[l,r],初始为[1,num[i].b]

这些num区间有三种情况:相交,相离,内含。因此我们需要对这三种情况进行处理。

那么我们很容易发现,只需要保证区间[l,r]只有同一个num中的a而没有b,

所以,根据上述原则,我们:

当前区间为[l,r],扫描到了第i个num

对于相离:此时应该另起炉灶重新划分区间。

因为num[i].a无论如何也加不进我们的当前区间了。我们新区间就是num[i]的[a,b-1],num[1..i].a都已经包含在上一个区间了,还会剩下一些num[1..i].b放在新区间,或者新区间与旧区间的间隔处(间隔处可以随意归给任意区间,不影响划分),而这些b由于a始终不可能被纳入新区间不要理会。但是,当我们扫描到最后一个区间时,需要给这些b单独划分一个区间,需要对最终分组数+ 1。也存在最有一个区间包含所有b的情况,不需要分组数+1,因此需要特判最后的b是不是最大的b(我写题解的时候才想到,我没有写进去,数据太水辣)。分组数ans加一。

对于相交或者内含:把r设置为min(b - 1, b)即可。因为r如果b不是已经扫描过的num中最小的,就一定有一个最小的包含在区间里,不符合设定。

这样,最终答案为ans + 2,因为最开始一个区间没有记录,最后面的b可能没有被包含进来(正如前面所说需要特判,但是数据太水,我没特判)

根据上述分析,我们发现:l根本用不到!!!只需要考虑r即可

上代码

#include

#include

#include

#include

#include

long long n;

int k;

struct T

{

int a,b;

}num[1000 + 10];

bool cmp(T q, T w){ return q.a < w.a;}

int ans;

int main()

{

freopen("data.txt", "r", stdin);

scanf("%d%d", &n, &k);

for(int i = 1;i <= k;i ++)

{

int temp,tempp;

scanf("%d%d", &temp, &tempp);

num[i].a = std::min(temp,tempp);

num[i].b = std::max(temp,tempp);

}

std::sort(num + 1,num + 1 + k, cmp);

int r = num[1].b - 1;

for(int i = 1; i <= k; i ++)

{

if(num[i].a > r)

{

ans ++;

r = num[i].b - 1;

}

r = std::min(r, num[i].b - 1);

}

printf("%d", ans + 2);

return 0;

}

美团外卖有哪几种配送方式?我们该如何选择?
DNF维护到几点?最新维护时间查询与高效安排攻略