POJ 1769 Minimizing maximizer

dp[i = 前i中sorter][j = 将min移动到j位置] = 最短的sorter序列。

对于sorteri只会更新它右边端点r的位置,因此可以把数组改成一维的,dp[r] = min(dp[r],dp[j]+1), l≤j<r。

不是滑窗,单调队列用用不了,但是可以用线段树去维护这个最小值。

/*********************************************************
*            ------------------                          *
*   author AbyssalFish                                   *
**********************************************************/
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
using namespace std;

#define para int o = 1, int l = 1,int r = n
#define TEMPvar int mid = (l+r)>>1, lc = (o<<1), rc = (o<<1|1);
#define lsn lc, l, mid
#define rsn rc, mid+1, r
#define insd ql<=l&&r<=qr
const int maxn = 5e4;
const int ST_SIZE = 1<<17;
const int INF = 0x3f3f3f3f;
int Min[ST_SIZE];
int n, m;
int dp[maxn+1];

void build(para)
{
    if(l == r){
        Min[o] = dp[l];
    }else {
        TEMPvar
        build(lsn);
        build(rsn);
        Min[o] = min(Min[lc],Min[rc]);
    }
}

int qpos,qval;
void update(para)
{
    if(l == r){
        Min[o] = qval;
    }else {
        TEMPvar
        if(qpos<=mid) update(lsn);
        else update(rsn);
        Min[o] = min(Min[lc],Min[rc]);
    }
}
int ql,qr;
int qMin(para)
{
    if(insd){ return Min[o]; }
    else {
        int res = INF;
        TEMPvar
        if(ql<=mid) res = min(res,qMin(lsn));
        if(qr>mid) res = min(res,qMin(rsn));
        return res;
    }
}

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    scanf("%d%d",&n,&m);
    memset(dp+2,0x3f,sizeof(int)*(n-1));
    build();
    for(int i = 0; i < m; i++){
        scanf("%d%d",&ql,&qr);
        if((qval = qMin()+1) < dp[qr]){
            dp[qpos = qr] = qval;
            update();
        }
    }
    printf("%d\n",dp[n]);
    return 0;
}
时间: 2024-10-12 21:09:59

POJ 1769 Minimizing maximizer的相关文章

POJ 1769 Minimizing maximizer(DP+zkw线段树)

[题目链接] http://poj.org/problem?id=1769 [题目大意] 给出一些排序器,能够将区间li到ri进行排序,排序器按一定顺序摆放 问在排序器顺序不变的情况下,一定能够将最大值交换到最后一位至少需要保留几个排序器 [题解] 我们发现,对于每个排序器,dp[ri]=min(dp[ri],min(dp[li]~dp[ri-1])+1) 我们用线段树对dp值进行最小值维护,顺序更新即可. [代码] #include <cstdio> #include <algorit

poj 1769 Minimizing maximizer(dp+线段树)

题意:数列长度为n,m次操作(n<=50000,m<=500000),每次操作将区间[si,ti]从小到大排序,求至少使用几次操作使数列的最后一个数与经过所有操作后相等: 思路:选取最少的操作得到最优解,一般采用dp; 假设原数列的第1个数为最大值,dp[j]表示最大值移动到第j个位置需要至少的操作数: 初始令dp[1]=0,dp[j]=inf(j>1); 对于每个i,有dp[ti]=min(dp[ti],min(dp[j](si<=j<=ti))+1); 若复杂度为O(nm

POJ 1769 Minimizing maximizer ( 线段树 &amp;&amp; DP )

题意 : 给定一个区间长度 n ,接下来给出 m 个子区间,要求最少选出多少个区间才能使得 1~n 这个区间被所选的所有子区间覆盖 分析 :  暴力枚举所有可能的组合可以达到 O( m^m ) ,完全不行 这里考虑动态规划解法 定义 dp[i][j] : 到第 i 个为止,完全覆盖点(即从 1~这个点都能保证被覆盖)到达第 j 个位置所需的最少子区间 则初始化为 dp[0][2~n] = INF.dp[0][1] = 0 假设当前第 i 个子区间用 ( si,ti ) 表示 则状态转移方程为 (

poj1769 Minimizing maximizer

poj1769 Minimizing maximizer 总之,存代码 = = #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int MAXN = 500000+10; const int MAXM = 500000+10; const int INF

Minimizing Maximizer

题意: 最少需要多少个区间能完全覆盖整个区间[1,n] 分析: dp[i]表示覆盖[1,i]最少需要的区间数,对于区间[a,b],dp[b]=min(dp[a...b-1])+1;用线段树来维护区间最小值. #include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdi

HOJ 题目分类

转自:http://blog.sina.com.cn/s/blog_65f3869301011a1o.html ******************************************************************************* 简单题(包括枚举,二分查找,(复杂)模拟,基础数据结构(栈.队列),杂题等 ****************************************************************************

POJ No.1769

分类:dp | 线段树 题意转化:用m个区间去覆盖1~n,求所需区间的最小数目. 分析:假设输入的n个数中第i个数是应该输出的最大值,则通过所选若干区间的操作后,若能将其从第i个位置移动到第n个,则Maximizer正常工作.由分析可知,如果i = 1时maxmizer可以正常工作,则对于任意地i都可以正常工作.所以,不妨假设输入的第一个数是应该输出的最大值,然后利用DP求解. dp[i]:= 将最大值从位置1移动到位置i时所需的最小区间数. 初始化: dp[1] = 0(不需要移动时所需区间数

POJ 3449 Geometric Shapes --计算几何,线段相交

题意: 给一些多边形或线段,输出与每一个多边形或线段的有哪一些多边形或线段. 解法: 想法不难,直接暴力将所有的图形处理成线段,然后暴力枚举,相交就加入其vector就行了.主要是代码有点麻烦,一步一步来吧. 还有收集了一个线段旋转的函数. Vector Rotate(Point P,Vector A,double rad){ //以P为基准点把向量A旋转rad return Vector(P.x+A.x*cos(rad)-A.y*sin(rad),P.y+A.x*sin(rad)+A.y*co

ACM训练方案-POJ题目分类

ACM训练方案-POJ题目分类 博客分类: 算法 ACM online Judge 中国: 浙江大学(ZJU):http://acm.zju.edu.cn/ 北京大学(PKU):http://acm.pku.edu.cn/JudgeOnline/ 杭州电子科技大学(HDU):http://acm.hdu.edu.cn/ 中国科技大学(USTC):http://acm.ustc.edu.cn/ 北京航天航空大学(BUAA)http://acm.buaa.edu.cn/oj/index.php 南京