P1868 饥饿的奶牛

P1868 饥饿的奶牛

题目描述

有一条奶牛冲出了围栏,来到了一处圣地(对于奶牛来说),上面用牛语写着一段文字。

现用汉语翻译为:

有N个区间,每个区间x,y表示提供的x~y共y-x+1堆优质牧草。你可以选择任意区间但不能有重复的部分。

对于奶牛来说,自然是吃的越多越好,然而奶牛智商有限,现在请你帮助他。

输入输出格式

输入格式:

第一行,N,如题

接下来N行,每行一个数x,y,如题

输出格式:

一个数,最多的区间数

输入输出样例

输入样例#1: 复制
3
1 3
7 8
3 4
输出样例#1: 复制
5

说明

1<=n<=150000

0<=x<=y<=3000000

洛谷题解:

其实这题一看数据x<=3000000就知道这题dp方程还是很好想的

dp[i]表示牛走到i这个位置能吃到的最大草数,

于是就有dp方程:dp[s[j].y]=max(dp[s[j].x-1]+s[i].y-s[i].x+1,dp[s[j].y];

这题背包要超时

以下是代码:

 刷表法,用当前的点,去更新其它的所有点

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn=5000000+10;
 7 struct nod
 8 {
 9     int x,y;
10 }s[maxn];
11 int dp[maxn];
12 int n,maxx,ans;
13 bool cmp(nod a,nod b)
14 {
15     return a.x==b.x?a.y<b.y:a.x<b.x;
16 }
17 int main()
18 {
19     scanf("%d",&n);
20     for(int i=1;i<=n;i++)
21     {
22         scanf("%d%d",&s[i].x,&s[i].y);
23         maxx=max(maxx,s[i].y);
24     }
25     //按x从小到大排序 
26     sort(s+1,s+n+1,cmp);
27     int j=1;
28     //枚举起点,但是我们dp用的终点 
29     for(int i=0;i<=maxx;i++)
30     {
31         //借用前一个节点的值 
32         dp[i]=max(dp[i],dp[i-1]);
33         //对于同一起点的区间,找里面最大的 
34         while(s[j].x==i && j<=n)
35         {
36             dp[s[j].y]=max(dp[s[j].y],dp[s[j].x-1]+s[j].y-s[j].x+1);
37             j++;
38         }
39         ans=max(ans,dp[i]);
40     }printf("%d
",ans);
41 }
原文地址:https://www.cnblogs.com/Renyi-Fan/p/7753285.html