D e s c r i p t i o n Description Description
有一排窗口,现有 B B B种方案,每种方案代表一段窗口,现在要使用的方案所覆盖的窗口没有重叠,且覆盖窗口最多,问在不重叠的情况下覆盖的最多数量的窗口
I n p u t Input Input
第一行,整数B。
第2到B+1行,每行两个整数,表示一个区间,较小的端点在前面。
O u t p u t Output Output
一行一个整数,表示他最多能吃到多少个窗口里的食物。
S a m p l e Sample Sample I n p u t Input Input
3
1 3
7 8
3 4
S a m p l e Sample Sample O u t p u t Output Output
5
H i n t Hint Hint
【数据范围】 对于100%的数据:1<=N<=2000,1<=B<=1000。
T r a i n Train Train o f of of T h o u g h t Thought Thought
将终点排序,然后从第一个终点枚举至n点(所有方案中的最大终点),判断是否可以连一个区间:
f
[
i
]
=
m
a
x
(
f
[
i
−
1
]
,
(
f
[
A
[
j
]
−
1
]
+
(
B
[
j
]
−
A
[
j
]
+
1
)
)
)
f[i]=max(f[i-1],(f[A[j]-1]+(B[j]-A[j]+1)))
f[i]=max(f[i−1],(f[A[j]−1]+(B[j]−A[j]+1)))
C o d e Code Code
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int maxx,B,f[2005];
struct Dio
{
int st,end;
}w[1001];
bool JOJO(Dio i,Dio j)
{return i.end<j.end;}
int main()
{
// freopen("hunger.in","r",stdin);
// freopen("hunger.out","w",stdout);
scanf("%d",&B);
for (int i=1; i<=B; ++i)
{
scanf("%d%d",&w[i].st,&w[i].end);
maxx=max(w[i].end,maxx);
}
sort(w+1,w+B+1,JOJO);//排序
for (int i=w[1].end; i<=maxx; ++i)
{
f[i]=f[i-1];
for (int j=1; j<=B; ++j)
{
if (w[j].end>i) break;//超出范围就不再有意义了
f[i]=max(f[i],f[w[j].st-1]+w[j].end-w[j].st+1);//动态转移方程
}
}
printf("%d",f[maxx]);
return 0;
}