zoukankan      html  css  js  c++  java
  • UVA 11134 FabledRooks 传说中的车 (问题分解)

    摘要:贪心,问题分解。

    因为行列无关,所以这个二维问题可以分解成两个一维问题。

    优先队列实现:类似区间点覆盖的问题,先按照左端点排序,相同然后在按右端点排序(灵活性小的优先选)。最优的选法,当然是要使选的这个点经过的区间越少越好,那么就选最左边的点,因为选右边可能多经过区间,一定不比选最左边的更优。选完之后,就要把选过的点last忽略,并且把包含这个点的区间做修改,这个修改是动态的,可用优先队列

    71ms

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 5003;
    struct seg
    {
        int l,r,id;
        seg(int L,int R) { l = L; r = R; }
        seg(){}
        bool operator < (const seg& rhs) const {
            return l > rhs.l || ( l == rhs.l && r > rhs.r);
        }
    };
    
    seg dim[2][maxn];
    int rooks[maxn][2];
    
    priority_queue<seg> q;
    
    bool solve(int n,int d)
    {
        for(int i = 0; i < n; i++){
           q.push(dim[d][i]);
        }
        int last = 0;
        int id = 0;
        while(q.size()){
            seg cur = q.top(); q.pop();
            if(cur.l>cur.r) return false;
            if(cur.l<=last) {
                cur.l = last + 1; q.push(cur);
            }else {
                last = cur.l;
                rooks[cur.id][d] = cur.l;
            }
        }
        return true;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int n;
        seg *R = dim[0], *C = dim[1];
        for(int i = 0; i < maxn; i++) dim[0][i].id = dim[1][i].id = i;
        while(~scanf("%d",&n)&&n){
            for(int i = 0; i < n; i++){
                scanf("%d%d%d%d",&R[i].l,&C[i].l,&R[i].r,&C[i].r);
            }
            if(solve(n,0)&&solve(n,1)){
                 for(int i = 0; i < n; i++){
                printf("%d %d
    ",rooks[i][0],rooks[i][1]);
                }
            }else puts("IMPOSSIBLE");
    
        }
        return 0;
    }
    优先队列

    另外一种贪心,直接按照右端点排序,优先处理右端点最小的区间,因为它的灵活性最小。从左往右边选点,使当前点尽量避免经过没有选点的区间。

    这样做的效率要更高

    11ms

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 5003;
    struct seg
    {
        int l,r,id;
        bool operator < (const seg& rhs) const {
            return r < rhs.r ;
        }
    };
    
    seg dim[2][maxn];
    int rooks[maxn][2];
    
    
    bool solve(int n,int d)
    {
        int last = -1;
        seg *Dim = dim[d];
        bool vis[n+1];
        memset(vis,0,sizeof(vis));
        sort(Dim,Dim+n);
        for(int i = 0; i < n; i++){
            int j;
            for(j = Dim[i].l; j <= Dim[i].r; j++) if(!vis[j]) {
                    rooks[Dim[i].id][d] = j; vis[j] = true; break;
            }
            if(j>Dim[i].r) return false;
        }
        return true;
    }
    
    int main()
    {
        int n;
        seg *R = dim[0], *C = dim[1];
        while(~scanf("%d",&n)&&n){
            for(int i = 0; i < n; i++){
                scanf("%d%d%d%d",&R[i].l,&C[i].l,&R[i].r,&C[i].r);
                R[i].id = C[i].id = i;
            }
            if(solve(n,0)&&solve(n,1)){
                 for(int i = 0; i < n; i++){
                printf("%d %d
    ",rooks[i][0],rooks[i][1]);
                }
            }else puts("IMPOSSIBLE");
    
        }
        return 0;
    }
    右端排序
  • 相关阅读:
    sessionStorage 、localStorage 和 cookie 之间的区别 及共同点:
    [转]css文件和js文件后面带一个问号
    Asp.net中动态设置标题Title,Keyword,Descripton标签的方法
    【11.7校内测试】【倒计时3天】【不想写题解】
    【洛谷】1600:天天爱跑步【LCA】【开桶】【容斥】【推式子】
    【11.6校内测试】【倒计时4天】【找规律?思维】【二分+倍增】
    【洛谷】3960:列队【Splay】
    CF733F Drivers Dissatisfaction【链剖】【最小生成树应用】
    【11.5校内测试】【倒计时5天】【DP】【二分+贪心check】【推式子化简+线段树】
    【11.2晚校内测试】【装桶模拟】【单调栈】
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4692756.html
Copyright © 2011-2022 走看看