POJ 1769 Minimizing maximizer 线段树优化DP

题意抽象出数学模型就是说“最少需要多少个区间能完全覆盖整个区间[1,n]”。

一开始没看到“ subsequence of the given sequence” ,直接排序,然后二分查找,居然1A。。充满了奇迹。

AC后百度题解发现自己看错题也能AC,相当自豪!

dp[i]表示覆盖[1,i]最少需要的区间数。

那么对于某段区间[a,b],dp[b]=min(dp[a....b-1])+1;

更新只需更新一点,不用一段。

还有几个细节

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<sstream>
#include<cmath>
#include<climits>
#include<string>
#include<map>
#include<queue>
#include<vector>
#include<stack>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define pb(a) push(a)
#define INF 0x1f1f1f1f
#define lson idx<<1,l,mid
#define rson idx<<1|1,mid+1,r
#define PI  3.1415926535898
template<class T> T min(const T& a,const T& b,const T& c) {
    return min(min(a,b),min(a,c));
}
template<class T> T max(const T& a,const T& b,const T& c) {
    return max(max(a,b),max(a,c));
}
void debug() {
#ifdef ONLINE_JUDGE
#else

    freopen("d:\in1.txt","r",stdin);
    freopen("d:\out1.txt","w",stdout);
#endif
}
int getch() {
    int ch;
    while((ch=getchar())!=EOF) {
        if(ch!=' '&&ch!='
')return ch;
    }
    return EOF;
}

const int maxn=50005;
int n,m;
int dp[maxn<<2];
int minv[maxn<<2];



struct Sorter
{
    int i,j;
    bool operator < (const Sorter &ant) const
    {
        if(j!=ant.j)return j<ant.j;
        else return i<ant.i;
    }
}sorter[maxn*10];

void PushUp(int idx)
{
    minv[idx]=min(minv[idx<<1],minv[idx<<1|1]);
}
int build(int idx,int l,int r)
{
    if(l==r)
    {
        if(l==1)minv[idx]=0;
        else minv[idx]=INF;
        return 0;
    }
    int mid=(r+l)>>1;
    build(lson);
    build(rson);
    PushUp(idx);
    return 0;
}
int update(int idx,int l,int r,int pos,int v)
{
    if(l==r)
    {
        minv[idx]=min(minv[idx],v);
        return 0;
    }
    int mid=(r+l)>>1;
    if(pos<=mid)update(lson,pos,v);
    else update(rson,pos,v);
    PushUp(idx);
    return 0;
}

int query(int idx,int l,int r,int tl,int tr)
{
    if(tl<=l&&tr>=r)
        return minv[idx];
    int mid=(r+l)>>1;

    int res=INF;
    if(tl<=mid) res=min(res,query(lson,tl,tr));
    if(tr>mid)  res=min(res,query(rson,tl,tr));
    return res;
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=0;i<m;i++)
            scanf("%d %d",&sorter[i].i,&sorter[i].j);
        //sort(sorter,sorter+m);
        build(1,1,n);
        for(int i=0;i<m;i++)
        {
            int minx=query(1,1,n,sorter[i].i,sorter[i].j-1);
            if(minx!=INF)
                update(1,1,n,min(n,sorter[i].j),minx+1);
        }
        printf("%d
",query(1,1,n,n,n));
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/BMan/p/3596767.html