捕老鼠

Description

为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里的仓库灭灭鼠。于是,猫被农夫约派去捕老鼠。 猫虽然擅长捕老鼠,但是老鼠们太健美了,身手敏捷,于是猫想到了一个绝妙的办法:它决定点燃纯艾条,用烟熏老鼠。 农夫约的农庄里有N 个仓库,排成了一排,编号为1~N。
假设猫在第i 个仓库点燃艾条,烟雾就会充满该仓库,并向左右扩散Ai的距离,接着所有|i-j|<=Ai 的仓库j 的老鼠被消灭。 猫是一只爱护空气环境的好猫,它希望知道最少需要多少支艾条,才可以消灭所有老鼠。

solution

正解:贪心
从左往右贪心,首先第一只老鼠必须消灭,那么肯定选择能够消灭到它的范围最大的一个,然后找到这个最远范围,将其中的老鼠顺便消灭,记录一下能够消灭到范围外的第一只老鼠的范围最广的一个艾条,然后一直贪心到最右边即可,对于扩展范围的求法,是基本套路,可以 \(dp\) 求出,\(dp[l]=max(dp[l],r)\)\(dp[i]=max(dp[i],dp[i-1])\)

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=500005;
int a[N],n,dp[N];
void work()
{
	int t;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]),t=Max(i-a[i],1),dp[t]=max(dp[t],i+a[i]);
   for(int i=1;i<=n;i++)dp[i]=Max(dp[i],dp[i-1]);

	int ans=0,i=1,lim=dp[1],v=0;
	while(i<=n){
	   while(i<=lim && i<=n)i++,v=Max(v,dp[i]);
		lim=v;
		v=0;
		ans++;
	}
	cout<<ans<<endl;
}

int main()
{
	work();
	return 0;
}

posted @ 2017-11-09 14:55  PIPIBoss  阅读(405)  评论(0编辑  收藏  举报