zoukankan      html  css  js  c++  java
  • POJ 2373

    原本一道挺简单的DP题,思路有了,运用单调队列,但在写单调队列时写挫了。。。

    这道题只需要计算偶数位置的即可,这是显而易见的,我有注意过这情况,写的时候却没在意。。。--!

    加入队列的元素应该当前now之前的now-2*A的元素,我开始不是每计算一个now位置就加入now-2*A的元素,搞得不是O(L)的复杂度。这次吸取教训了。。记得DP时使用单调队列一般每计算一个位置加入一个元素。

    PS:

    又回想起之前比赛,感觉很害怕。。希望自己加油吧。

    我的代码:不知为何没能过。。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <climits>
    #include <string.h>
    #include <queue>
    #include <cmath>
    #include <vector>
    
    using namespace std;
    const int N=1000100;
    const int inf=1<<30;
    
    int dp[N],que[N],f,l,p;
    struct Node{
    	int l,r;
    	Node(){l=0,r=0;}
    	Node(int ll,int rr){l=ll,r=rr;}
    	bool operator <(const Node &a)const{
    		if(l<a.r) return true;
    		return false;
    	}
    };
    Node node[1010];
    
    int n,L,a,b;
    
    void Mergeinter(){
    /*	int top=0;
    	for(int i=1;i<n;i++){
    		if(node[i].l<node[top].r&&node[top].r<node[i].r)
    		node[top].r=node[i].r;
    		else if(node[i].l<node[top].r&&node[top].r>=node[i].r) continue;
    		else{
    			top++;
    			node[top].l=node[i].l;
    			node[top].r=node[i].r;
    		}
    	}
    	n=top;*/
        int top=0;   
        int l=node[0].l,r=node[0].r;  
        for(int i=1;i<n;i++){  
            if(node[i].l<r){  
                r=max(r,node[i].r);  
            }else{  
                node[top++]=Node(l,r);  
                l=node[i].l;  
                r=node[i].r;  
            }  
        }  
        node[top++]=Node(l,r);  
        n=top;  
    }
    
    void Pop(int now){
    	while(f<l){
    		if(now-que[f]<=b) break;
    		f++;
    	}
    }
    
    void Push(int now){
    	while(f<l){
    		if(dp[que[l-1]]<dp[now-a]) break;
    		l--;
    	}
    	que[l++]=now-a;
    }
    
    int main(){
    	while(scanf("%d%d",&n,&L)!=EOF){
    		scanf("%d%d",&a,&b);
    		for(int i=0;i<n;i++){
    			scanf("%d%d",&node[i].l,&node[i].r);
    		}
    		if(L%2==1){ printf("-1
    ");continue; }	
    		f=l=p=0;
    		sort(node,node+n);
    		Mergeinter();
    		a*=2;b*=2;
    		dp[0]=0;
    		for(int i=2;i<a;i+=2) dp[i]=inf;
    		for(int i=a;i<=L;i+=2){
    			Pop(i);
    			Push(i);
    			while(p<n&&node[p].r<=i) p++;
    			if(p<n&&node[p].l<i||dp[que[f]]==inf) dp[i]=inf;
    			else dp[i]=dp[que[f]]+1;
    		}
    		if(dp[L]==inf) printf("-1
    ");
    		else printf("%d
    ",dp[L]);
    	}
    	return 0;
    }
    

      

    引用别人的:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <algorithm>
    using namespace std;
    const int MAX=1001000;
    const int oo=0x3f3f3f3f;
    int dp[MAX];
    struct Seg{
    	int x,y;
    	Seg(int x=0,int y=0):x(x),y(y){}
    	bool operator<(const Seg& seg) const{
    		return x<seg.x;
    	}
    }seg[1100];
    int q[MAX],id[MAX],f,b;
    int merge(int n){
    	int top=0;
    	sort(seg,seg+n);
    	int l=seg[0].x,r=seg[0].y;
    	for(int i=1;i<n;i++){
    		if(seg[i].x<r){
    			r=max(r,seg[i].y);
    		}else{
    			seg[top++]=Seg(l,r);
    			l=seg[i].x;
    			r=seg[i].y;
    		}
    	}
    	seg[top++]=Seg(l,r);
    	return top;
    }
    int main(){
    	int n,L,l,r,p;
    	scanf("%d%d",&n,&L);
    	if(L&1){
    		printf("%d
    ",-1);
    		return 0;
    	}
    	scanf("%d%d",&l,&r);
    	for(int i=0;i<n;i++){
    		scanf("%d%d",&seg[i].x,&seg[i].y);
    	}
    	n=merge(n);
    	l<<=1;
    	r<<=1;
    	dp[0]=0;
    	f=b=0;
    	p=0;
    	dp[0]=0;
    	for(int i=2;i<l;i+=2)dp[i]=oo; //start with 2.
    	for(int i=l;i<=L;i+=2){
    		while(f!=b&&i-id[f]>r)f++;
    		while(f!=b&&q[b-1]>=dp[i-l])b--;
    		id[b]=i-l;
    		q[b++]=dp[i-l];
    		while(p<n&&seg[p].y<=i)p++;
    		if(p<n&&seg[p].x<i||q[f]==oo)dp[i]=oo;	 //if q[f] is oo, not to set dp[i] = q[f]+1.
    		else dp[i]=q[f]+1;
    	}
    	//for(int i=0;i<=L;i+=2)printf("%d ",dp[i]==oo?-1:dp[i]);puts("");
    	printf("%d
    ",dp[L]==oo?-1:dp[L]);
    	
    	return 0;
    }
    

      

  • 相关阅读:
    大神语录1 如何滑动fragmentmanager里面一个fragment里面的viewgroup---dispatchTouchEvent 、onInterceptTouchEvent 、onTouchEvent
    转载-好的简历
    安卓开发8- 安卓开源项目整理github
    安卓开发7-网络通信-如何使用webservice
    安卓开发6 -Viewpager+fragment更新数据
    leetcode rotatenumber
    Java程序执行时间的简单方法
    LeetCode happyint
    安卓开发5-fragment和activity
    [转]深入理解AsyncTask的工作原理
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4301896.html
Copyright © 2011-2022 走看看