【JZOJ】【DP】饥饿的WZK

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[i1],(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; 
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值