ZOJ 3963 STL + 贪心

来源:互联网 发布:网站数据库泄露 2017 编辑:程序博客网 时间:2024/06/03 21:46

STL + 贪心

题意:

​ 有n个数字,它们可以再限制条件下可以建树:ai<aj,i<j ,满足ai是aj 的父亲节点,一个父亲节点只能最多连两个儿子,现在要求满足条件下如何建树使得树的数量最少,输出每一个树 的大小和节点。

思路:

​ 这题考察STL和思维能力,若想使得树建的少,那么在插入的节点的时候要寻找比自己小的数字,按照贪心的思想一定要找第一个比自己小的数字,这样才能让后边的节点有更多的机会成为子节点。

​ 用set维护父亲节点,当然必须要是儿子数量不能超过2,超过就删除。当一个节点找不到比自己小的,只能另外再建树即可。

  • 增长见识的地方是:memset里面用sizeof超时!!!利用本身占的字节快。
#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <set>using namespace std;const int maxn = 1e5+10;int a[maxn];struct Node{    int anspos;    int pos;    bool operator <(Node b) const    {        if(a[pos] == a[b.pos]) return pos < b.pos;        return a[pos] < a[b.pos];    }}node;int n;vector<int>ans[maxn];int num[maxn];set<Node>s;set<Node>::iterator it;int main(){    //freopen("in.txt","r",stdin);    int t;    scanf("%d",&t);    while(t--) {        s.clear();        int cnt = 0;        scanf("%d",&n);        memset(num,0,4*n+4);        //memset(num,0,sizeof(num));        for(int i = 1;i <= n; i++) {            scanf("%d",&a[i]);            node.pos = i;            it = s.upper_bound(node);            if(it == s.begin()) {                node.anspos = cnt;                s.insert(node);                ans[cnt].push_back(i);                cnt++;            }            else {                it--;                node = *it;                num[node.pos]++;                if(num[node.pos] >= 2) {                    s.erase(it);                }                node.pos = i;                s.insert(node);                ans[node.anspos].push_back(i);            }        }        printf("%d\n",cnt);        for(int i = 0;i < cnt; i++) {            int len = ans[i].size();            printf("%d",len);            for(int j = 0;j < len; j++) {                printf(" %d",ans[i][j]);            }            printf("\n");            ans[i].clear();        }    }    return 0;}
原创粉丝点击