zoukankan      html  css  js  c++  java
  • #树状数组、dp#JZOJ 5361 捕老鼠

    题目

    农夫约的农庄里有(N)个仓库,排成了一排,编号为(1~N)
    假设猫在第(i)个仓库点燃艾条,烟雾就会充满该仓库,并向左右扩散(Ai)的距离,接着所有(|i-j|<=Ai) 的仓库(j) 的老鼠被消灭。
    猫是一只爱护空气环境的好猫,它希望知道最少需要多少支艾条,才可以消灭所有老鼠。


    分析

    考虑处理出每个右端点能同时扩散的最小的左端点,
    那么状态转移方程显然,用数据结构维护


    代码

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #define rr register
    using namespace std;
    const int N=500011; int c[N],f[N],dp[N],n;
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline signed min(int a,int b){return a<b?a:b;}
    inline signed fan(int x){return n-x+1;}
    inline signed query(int x){
    	rr int ans=f[0];
    	for (;x;x-=-x&x)
    	    ans=min(ans,c[x]);
    	return ans;
    }
    inline void update(int x,int y){
    	for (;x<=n;x+=-x&x) c[x]=min(c[x],y);
    }
    signed main(){
    	freopen("cat.in","r",stdin);
    	freopen("cat.out","w",stdout); 
    	n=iut()+1,memset(f,0x3f,sizeof(f));
    	for (rr int i=1;i<n;++i){
    		rr int x=iut(),R=min(i+x,n-1);
    		f[R]=min(f[R],(i<=x)?1:(i-x));
    	}
    	memset(c,0x3f,sizeof(c)),update(fan(1),dp[1]=0);
    	for (rr int i=1;i<n;++i) if (f[i]<=i)
    	    update(fan(i+1),dp[i+1]=query(fan(f[i]))+1);
    	return !printf("%d",dp[n]);
    } 
    
  • 相关阅读:
    matlab简单线性规划&单纯形法
    matlab多变量绘图函数(类似ggplot2)
    matlab近似泛函优化
    如何求矩阵的逆矩阵
    数值分析手写笔记
    latex绘图小结
    数理统计手写笔记
    matlab kriging模型
    运筹学与最优化手写笔记
    matlab既约梯度法习题
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13916620.html
Copyright © 2011-2022 走看看