zoukankan      html  css  js  c++  java
  • CF GYM 100703I Endeavor for perfection

    题意:有n个学习领域,每个领域有m个课程,学习第i个领域的第j个课程可以获得sij个技能点,在每个领域中选择一个课程,要求获得的n个技能点的最大值减最小值最小,输出符合要求的策略。

    解法:尺取法。将课程的技能点按值进行排序,同时要记录每个值对应的领域,用尺取法选择第一段包含全部领域的区间,区间的边界即为最值,然后将左指针逐步右移,直到出现有的领域没有选课,继续右移右指针,直到结束。当右指针已移到最右的时候需要特判,只移动左指针。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<limits.h>
    #include<time.h>
    #include<stdlib.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define LL long long
    using namespace std;
    int c[205];
    struct node
    {
        int a, b, c;
        bool operator < (const node &tmp) const
        {
            if(a == tmp.a)
                return b < tmp.b;
            return a < tmp.a;
        }
        bool operator == (const node &tmp) const
        {
            return a == tmp.a && b == tmp.b;
        }
        node(int a, int b, int c) : a(a), b(b), c(c){}
        node() {}
    };
    vector <node> v;
    int n;
    bool judge(int cnt[])
    {
        for(int i = 0; i < n; i++)
            if(!cnt[i])
                return false;
        return true;
    }
    int main()
    {
        while(~scanf("%d", &n))
        {
            v.clear();
            for(int i = 0; i < n; i++)
            {
                scanf("%d", &c[i]);
            }
            if(n == 1 && c[0] == 1) //需要特判否则RE
            {
                int x;
                scanf("%d", &x);
                printf("0
    1
    ");
                continue;
            }
            for(int i = 0; i < n; i++)
            {
                for(int j = 0; j < c[i]; j++)
                {
                    int s;
                    scanf("%d", &s);
                    v.push_back(node(s, i, j + 1));
                }
            }
            sort(v.begin(), v.end());
            v.erase(unique(v.begin(), v.end()), v.end());
            int len = v.size();
            int flag = 0;
            int now = -1;
            int cnt[205] = {0};
            int l = 0, r = 0;
            cnt[v[0].b] = 1;
            int ans = INT_MAX, pl, pr;
            for(; l < len;)
            {
                if(!flag)
                {
                    r++;
                    cnt[v[r].b]++;
                    if(judge(cnt))
                    {
                        flag = 1;
                        if(v[r].a - v[l].a < ans)
                        {
                            ans = v[r].a - v[l].a;
                            pl = l, pr = r;
                        }
                        continue;
                    }
                }
                else 
                {
                    if(~now && r < len - 1)
                    {
                        r++;
                        cnt[v[r].b]++;
                        if(cnt[now])
                        {
                            now = -1;
                            if(v[r].a - v[l].a < ans)
                            {
                                ans = v[r].a - v[l].a;
                                pl = l, pr = r;
                            }
                        }
                    }
                    else
                    {
                        if(r == len - 1)
                        {
                            cnt[v[l].b]--;
                            l++;
                            if(judge(cnt))
                            {
                                if(v[r].a - v[l].a < ans)
                                {
                                    ans = v[r].a - v[l].a;
                                    pl = l, pr = r;
                                }
                            }
                            continue;
                        }
                        cnt[v[l].b]--;
                        if(!cnt[v[l].b])
                        {
                            now = v[l].b;
                            l++;
                        }
                        else
                        {
                            l++;
                            if(v[r].a - v[l].a < ans)
                            {
                                ans = v[r].a - v[l].a;
                                pl = l, pr = r;
                            }
                        }
                    }
                }
            }
            printf("%d
    ", ans);
            int prt[205];
            for(int i = pl; i <= pr; i++)
            {
                prt[v[i].b] = v[i].c;
            }
            for(int i = 0; i < n; i++)
            {
                if(i)
                    printf(" ");
                printf("%d", prt[i]);
            }
            puts("");
        }
        return 0;
    }
    

      

  • 相关阅读:
    对SVM的个人理解---浅显易懂
    机器学习方法总结
    机器学习&数据挖掘笔记_16(常见面试之机器学习算法思想简单梳理)
    语音信号处理之(一)动态时间规整(DTW)
    libSVM 参数选择
    Chrome调试工具
    Spring 框架的搭建及测试
    单例模式的Oracle 数据库连接应用
    Java 连接 Oracle 数据库
    组件的插件开发
  • 原文地址:https://www.cnblogs.com/Apro/p/4685296.html
Copyright © 2011-2022 走看看