【LG P1868】饥饿的奶牛

这篇题解记录了我做这道题的思考过程。

题目分析

有人曾经说过:你不会的题很可能就是动态规划。

这道题就是动态规划。

区间?感觉是线性动态规划,再看数据范围,没错了。

状态定义

首先不妨想象这些草地是一个一个的格子。

先从最简单的定义想起:

(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;
}

参考资料

题解 P1868 【饥饿的奶牛】 - zhy137036 的博客 - 洛谷博客

知识共享许可协议

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。

限于本人水平,如果文章有表述不当之处,还请不吝赐教。

原文地址:https://www.cnblogs.com/Sam2007/p/15027070.html