2015 多校联赛 ——HDU5360(贪心+优先队列)

 

Sample Input
4 8 4 1 3 2 2 1 0 3 5 3 6 4 2 1 7 6 8 3 3 2 0 5 0 3 6 4 5 2 7 7 6 7 6 8 2 2 3 3 3 0 0 2 7 4 3 6 3 2 2 5 8 5 6 5 3 3 1 2 4 6 7 7 6 5 4 3 5
 

 

Sample Output
7 1 7 6 5 2 4 3 8 8 4 6 3 1 2 5 8 7 7 3 6 7 1 5 2 8 4 0 1 2 3 4 5 6 7 8

 

 

找出能约出最多人的顺序。  假设前面已经有x人同意了,对于第i个人而言, l[i] <= x <= r[i] ,则第i个人同意。求以怎样的顺序去找人最合适。


感觉思路大致方向是对的,只是方法上有些问题,不够简便(- -)

在同l都满足的情况下,选择的r要尽可能的小,才能保证后面选的更多

scanf("%d",&tmp);  

q[p[i]].push_back(node(tmp,i));


p[i]是它的左边,tmp是右边,用这样保存的话在查找的时候便不用查找全部。(详细看代码)

每次查找后都保证了(l[i] <= i 的全部被包括了,感觉别人好机智 。。)


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;

struct node
{
    int b, num;
    node() {}
    node( int _b, int _num )
    {
        b = _b, num = _num;
    }
    bool operator < ( const node & l ) const
    {
        return b > l.b;
    }
};
int p[100010];
int n;
int rec[100010];
int vis[100010];
int aim;
vector<node>q[100010];
priority_queue<node>que;


int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        aim=0;
        memset(vis,0,sizeof(vis));
        scanf("%d",&n);
        for(int i = 0;i <= n;i++)
            q[i].clear();

        for(int i=1; i<=n; i++)
        {
            scanf("%d",&p[i]);
        }
        
        for(int i=1; i<=n; i++)            
        {
            int tmp;
            scanf("%d",&tmp);
            q[p[i]].push_back(node(tmp,i));           //用左边界来记录
        }

        while(1)
        {
            int flag = 0;
            for(int i=0; i < q[aim].size(); i++)      //这里就不需要全部找一遍
            {
                    que.push(q[aim][i]);
            }
            while(!que.empty())
            {
                if(que.top().b>= aim && vis[que.top().num]!=1)
                {
                    vis[que.top().num]=1;
                    rec[aim] = que.top().num;
                    aim++;
                    que.pop();
                    flag = 1;
                    break;
                }
                que.pop();
            }
            if(!flag)
                break;
        }

        printf("%d\n",aim);
        if(aim)
        {
            printf("%d",rec[0]);
            for(int i=1; i<aim; i++)
                printf(" %d",rec[i]);

            for(int i=1; i<=n; i++)
            {
                if(vis[i]==0)
                    printf(" %d",i);
            }
        }
        else
        {
            printf("1");
            for(int i = 2; i <= n; i++)
                printf(" %d",i);
        }
        printf("\n");
    }
    return 0;
}

  

posted @ 2015-08-07 10:56  Przz  阅读(145)  评论(0编辑  收藏  举报