zoukankan      html  css  js  c++  java
  • POJ.1769.Minimizing maximizer(线段树 DP)

    题目链接

    /*
    题意:有m个区间,问最少要多少个区间能覆盖[1,n] 
    注:区间要按原区间的顺序,不能用排序贪心做 
    
    设dp[i]表示最右端端点为i时的最小值 
    dp[e[i]]=min{dp[s[i]]~dp[e[i]-1]}+1
    注意修改只需要修改右端点,不需要修改一段 
    所以线段树查询区间最小值即可 
    */
    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    #define gc() getchar()
    //#define gc() (TT==SS &&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),TT==SS)?EOF:*SS++)
    const int N=5e4+5,MAXIN=1e7,INF=0x3f3f3f3f;
    
    int n,m,f[N];
    char IN[MAXIN],*SS=IN,*TT=IN;
    struct Seg_Tree
    {
    	int tot;
    	struct Node
    	{
    		int l,r,val,ls,rs;
    	}node[N<<1];
    	inline void PushUp(int rt)
    	{
    		node[rt].val=std::min(node[node[rt].ls].val,node[node[rt].rs].val);
    	}
    	void Build(int l,int r)
    	{
    		int p=tot++;
    		node[p].l=l, node[p].r=r;
    		if(l==r){ node[p].ls=node[p].rs=-1,node[p].val=f[l]; return;}
    		int m=l+r>>1;
    		node[p].ls=tot, Build(l,m);
    		node[p].rs=tot, Build(m+1,r);
    		PushUp(p);
    //		printf("%d:l:%d r:%d val:%d
    ",p,l,r,node[p].val);
    	}
    	void Modify(int rt,int pos,int v)
    	{
    		if(node[rt].l==node[rt].r)
    		{
    			node[rt].val=v; return;
    		}
    		int m=node[rt].l+node[rt].r>>1;
    		if(pos<=m) Modify(node[rt].ls,pos,v);
    		else Modify(node[rt].rs,pos,v);
    		PushUp(rt);
    	}
    	int Query(int rt,int L,int R)
    	{
    		if(L<=node[rt].l && node[rt].r<=R) return node[rt].val;
    		int m=node[rt].l+node[rt].r>>1;
    		if(L<=m)
    			if(m<R) return std::min(Query(node[rt].ls,L,R),Query(node[rt].rs,L,R));
    			else return Query(node[rt].ls,L,R);
    		else if(m<R) return Query(node[rt].rs,L,R);
    	}
    }t;
    
    inline int read()
    {
    	int now=0,f=1;register char c=gc();
    	for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now*f;
    }
    
    int main()
    {
    	n=read(),m=read();
    	memset(f,0x3f,sizeof f);
    	f[1]=0;
    	t.Build(1,n);
    	int l,r,tmp;
    	while(m--)
    	{
    		l=read(),r=read();
    		if(f[r]>(tmp=t.Query(0,l,r-1)+1))
    			f[r]=tmp, t.Modify(0,r,tmp);
    	}
    	printf("%d",f[n]);
    
    	return 0;
    }
    
  • 相关阅读:
    思考c++编程-译自c++ programming language 1.7节
    对于(学习c++)的c程序员的建议
    输入框字数统计效果
    去掉tppabs冗余代码
    分享JS实现IE6 PNG完全透明(包括背景图片)
    系统启动过程
    VBP结构介绍
    python的xml文件操作
    javascript实现手动调整下拉列表框
    javaScript实现从一个下拉列表到另一个下拉列表
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8444258.html
Copyright © 2011-2022 走看看