其他分享
首页 > 其他分享> > 【DP】饥饿的WZK(jzoj 1998)

【DP】饥饿的WZK(jzoj 1998)

作者:互联网

饥饿的WZK

jzoj 1988

题目大意:

有很多个点,并且给出n个区间,问在选的区间不重复的前提下,选的区间的点数总和最大是多少

输入样例

3
1 3
7 8
3 4

输出样例

5

数据范围

对于100%的数据:1<=N<=2000,1<=B<=1000。

解题思路:

先按结束的位置给区间 排个序,然后记录下在当前区间前且能和当前区间一起选的区间中最后的区间(lastlastlast),然后设f[i]f[i]f[i]为前iii个区间的最大值,然后可以得出一下方程
f[i]=max(f[i1],f[a[i].last]+a[i].num)f[i]=max(f[i-1],f[a[i].last]+a[i].num)f[i]=max(f[i−1],f[a[i].last]+a[i].num)

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,f[2500];
struct rec
{
	int begin,end,num,last;
}a[2500];
bool cmp(rec x,rec y){return x.end<y.end;}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;++i)
	  {
	  	scanf("%d %d",&a[i].begin,&a[i].end);
		a[i].num=a[i].end-a[i].begin+1;//数字和
	  }
	sort(a+1,a+1+n,cmp);//排序
	for (int i=1;i<=n;++i)
	  for (int j=i-1;j>0;--j)
	  	if (a[j].end<a[i].begin)//记录last
	  	  {
	  	    a[i].last=j;
	  	    break;
		  }
	for (int i=1;i<=n;++i)
	  f[i]=max(f[i-1],f[a[i].last]+a[i].num);//要不不选,选了就和上一个可以一起有的一起选
	printf("%d",f[n]);
	return 0;
}

标签:last,1998,num,WZK,max,区间,rec,include,DP
来源: https://blog.csdn.net/ssllyf/article/details/95097459