zoukankan      html  css  js  c++  java
  • POJ 1769(Minimizing maximizer) 线段树优化的dp

    题意:是有一个装置可以输出n个数的最大值, 这个装置由m个排序器组成, 每个排序器可以将这n个数从s 到 t的数按照从小到大的顺序排列, 有一个人发现将m个排序器中的一些排序器去掉仍然不影响功能,  现在问你最少需要多少个排序器可以完成功能。

    思路:dp[i][j]表示更新到第i个区间,到第j个位置最小要几个区间。// 对线段树还是不太熟悉

    T代码:

    #include <queue>
    #include<iostream>
    #include<stdio.h>
    #include <string.h>
    #include <math.h>
    #include <algorithm>
    #include <ctime> 
    #include <queue>
    using namespace std;
    int dp[55000];
    int main(){
        int i,j,k,f1,f2,f3,f4,t1,t2,t3,t4,n,m;
    //    freopen("in.txt","r",stdin);
        cin >> n>> m;
            for(i=0;i<=n;i++)
        dp[i]=1e9+7;
        dp[1]=0;  //移动到1的费用为0 
        for(i=1;i<=m;i++){
            scanf("%d %d",&t1,&t2);
            for(j=t1;j<=t2;j++){
                if(j==t1){
                    f1=dp[j];
                    if(f1+1>=dp[t2])break;
                }else if(j>t1&&j<=t2){
                    dp[j]=min(dp[j],f1+1);
                }
        //    cout << j <<"的费用为"  << dp[j] << endl; 
            }
        }
        cout << dp[n] << endl;
        return 0;
    }
    View Code

    AC代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring> // for memset
    #include <vector> // push_back() // vector<int>().swap(v);
    #include <set> //multiset set<int,greater<int>> //big->small
    #include <map>
    #include <stack> // top()
    #include <queue> // front() // priority_queue<T,vector<T>,greater<T> >
    #include <cmath> // auto &Name : STLName  Name.
    #include <utility>
    #include <sstream>
    #include <string> // __builtin_popcount (ans); // 获取某个数二进制位1的个数
    #include <cstdlib> // rand()
    
    #define IOS ios_base::sync_with_stdio(0); cin.tie(0)
    #define lowbit(x) (x&(-x))
    using namespace std;
    typedef long long ll;
    
    const int INF = 0x3f3f3f3f;
    const int maxn = 5e5 + 5;
    struct T{
        int l,r,m;
    }tree[maxn*4];
    
    int ans,m,n,t1,t2;
    
    void build(int l,int r,int num)
    {
        tree[num].l=l;
        tree[num].r=r;
        if(l==r)
        {
            if(l==1)tree[num].m=0;
            else    tree[num].m=INF;
            return;
        }
        int m=(l+r)/2;
        build(l,m,num*2);
        build(m+1,r,num*2+1);
        tree[num].m=min(tree[num*2].m,tree[num*2+1].m);
    }
    
    int query(int l,int r,int num)
    {
        if(tree[num].l>=l&&tree[num].r<=r)
            return tree[num].m;
        int mid=(tree[num].l+tree[num].r)/2;
        if(l>mid){
            query(l,r,num*2+1);
        }else if(r<=mid){
            query(l,r,num*2);
        }else if(r>mid&&l<=mid){
            int v1=query(l,r,num*2);
            int v2=query(l,r,num*2+1);
            return min(v1,v2);
        }
    }
    
    void update(int num,int i,int c)
    {
        if(tree[num].l==tree[num].r&&tree[num].l==i)
        {
            tree[num].m=c;
            return;
        }
        int mid=(tree[num].l+tree[num].r)/2;
        if(i<=mid)  update(2*num,i,c);
        else    update(2*num+1,i,c);
        tree[num].m=min(tree[num*2].m,tree[num*2+1].m); 
    }
    
    int main(void)
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            build(1,n,1);
    
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d",&t1,&t2);
                int v1=query(t1,t2,1)+1;
                int v2=query(t2,t2,1);
                int v3=min(v1,v2);
                update(1,t2,v3);
            }
            printf("%d
    ",query(n,n,1));
        }
    
        return 0;
    }

      

  • 相关阅读:
    【洛谷P4708】—画画(Burnside引理)
    【HDU 6087】—Rikka with Sequence(可持久化平衡树)
    【HDU 6087】—Rikka with Sequence(可持久化平衡树)
    【Codeforces 643G】—Choosing Ads(线段树)
    【Codeforces 643G】—Choosing Ads(线段树)
    less sass学习总结(——待续哦——)
    网站常识
    网站发布流程
    解惑 和 遇到的问题
    页面无法访问 css文件加载问题
  • 原文地址:https://www.cnblogs.com/jaszzz/p/12997109.html
Copyright © 2011-2022 走看看