这篇题解记录了我做这道题的思考过程。
题目分析
有人曾经说过:你不会的题很可能就是动态规划。
这道题就是动态规划。
区间?感觉是线性动态规划,再看数据范围,没错了。
状态定义
首先不妨想象这些草地是一个一个的格子。
先从最简单的定义想起:
设 (f_i) 表示前 (i) 个格子最多能吃到多少牧草。
虽然这个定义很简单,但是很好用。
转移式
显然 (f_jge f_{j-1})。多一个格子选择,吃得总不会更少。
如果有一个区间 ((i,j)),那么 (f_jge f_{i-1}+j-i+1)。
最后得到转移式:
[large f_j=max(f_{j-1},max f_{i-1}+j-(i-1))
]
细节处理
但是怎么对于所有的 (j) 都知道对应的所有的 (i) 呢?
发现一个 (j) 所对应的 (i) 的个数是不固定的,所以想到用 vector<int>
保存。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1.5e5+5;
vector<int> v[N];
int f[N];
int main() {
int n,m=0;
scanf("%d",&n);
for(int i=1,x,y; i<=n; i++) {
scanf("%d %d",&x,&y),v[y].push_back(x),m=max(m,y);
}
for(int i=1; i<=m; i++) {
f[i]=f[i-1];
for(int j=0; j<v[i].size(); j++) {
int b=v[i][j]-1;
f[i]=max(f[i],f[b]+i-b);
}
}
printf("%d",f[m]);
return 0;
}