• BestCoder Round #91


    传送门:http://acm.hdu.edu.cn/search.php?field=problem&key=BestCoder+Round+%2391&source=1&searchmode=source

    A题:给你n种字母,每种字母有个权值vali,共cnti个,现在让你在里面挑出任意数量的字符,组合成一个字符串,该字符串的权值的计算方式为val1*1+val2*2+……+valn*n,让你输出字符串最大的权值是多少。这题很容易会有一个错误的贪心,就是把val为负的舍去,然后val从小到大选择。事实上负值时可以选的,比如字符1的权值为-1,字符2的权值为2,字符3的权值为3,那么如果我不选字符1,总权值为2*1+3*2=8,小于选了字符1的权值-1*1+2*2+3*3=12,所以这种贪心是错的。正解是先按val对字符排序,很明显,val大的字符如果不选,val小的就一定不会选。也即是,如果字符ch选了,权值比它大的肯定也会选。那假设它选了,总权值就会增加valch+valch+1,valch+2……valn,因此只要判断valch+valch+1,valch+2……valn是不是大于0,就能确定ch到底要不要选了。可以预处理下后缀和,然后直接扫一遍。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    #include <bitset>
    #define X first
    #define Y second
    #define clr(u,v); memset(u,v,sizeof(u));
    #define in() freopen("data","r",stdin);
    #define out() freopen("ans","w",stdout);
    #define Clear(Q); while (!Q.empty()) Q.pop();
    #define pb push_back
    
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int maxn = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    pii N[100];
    vector <int> V;
    int sum[maxn];
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while (T--)
        {
            V.clear();
            int n;
            scanf("%d", &n);
            for (int i = 0; i < n; i++)
            {
                scanf("%d%d", &N[i].X, &N[i].Y);
                while (N[i].Y--)
                    V.pb(N[i].X);
            }
            sort(V.begin(), V.end());
            sum[V.size()] = 0;
            for (int i = V.size() - 1; i >= 0; i--)
                sum[i] = sum[i+1] + V[i];
            ll ans = 0, k = 1;
            for (int i = 0; i < V.size(); i++)
                if (V[i] >= 0 || V[i] + sum[i+1] >= 0)
                {
                    ans += k * V[i];
                    k++;
                }
            printf("%I64d
    ", ans);
        }
        return 0;
    }
    View Code

    B题:有n种植物,每种植物有个适宜温度区间,如果温度适宜,它可以提供ai的研究价值,如果温度大于适宜温度的上限,它可以提供bi的研究价值,如果温度小于适宜温度的下限,它可以提供ci的研究价值。现在让你找到一个温度,使得总研究价值最大,温度可以为任意实数。输出最大总研究价值。先离散化一下温度,然后线段树维护下最大研究价值。注意由于温度是实数,所以离散的时候要,两个数之间要多加一个空位,用于浮点数的统计。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    #include <bitset>
    #define X first
    #define Y second
    #define clr(u,v); memset(u,v,sizeof(u));
    #define in() freopen("data","r",stdin);
    #define out() freopen("ans","w",stdout);
    #define Clear(Q); while (!Q.empty()) Q.pop();
    #define pb push_back
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    const int maxn = 2e5 + 10;
    const int inf = 0x3f3f3f3f;
    struct node1
    {
        int l, r, a, b, c;
    } N[maxn];
    vector<pii> V;
    LL add[maxn<<2];
    LL Max[maxn<<2];
    void PushUp(int rt)
    {
        Max[rt] = max(Max[rt<<1] , Max[rt<<1|1]);
    }
    void PushDown(int rt, int m)
    {
        if (add[rt])
        {
            add[rt<<1] += add[rt];
            add[rt<<1|1] += add[rt];
            Max[rt<<1] += add[rt];
            Max[rt<<1|1] += add[rt];
            add[rt] = 0;
        }
    }
    
    void update(int L, int R, int c, int l, int r, int rt)
    {
        if (L <= l && r <= R)
        {
            add[rt] += c;
            Max[rt] += c;
            return ;
        }
        PushDown(rt , r - l + 1);
        int m = (l + r) >> 1;
        if (L <= m) update(L , R , c , lson);
        if (m < R) update(L , R , c , rson);
        PushUp(rt);
    }
    LL query(int L, int R, int l, int r, int rt)
    {
        if (L <= l && r <= R)
        {
            return Max[rt];
        }
        PushDown(rt , r - l + 1);
        int m = (l + r) >> 1;
        LL ret = 0;
        if (L <= m) ret = max(ret, query(L , R , lson));
        if (m < R) ret = max(ret, query(L , R , rson));
        return ret;
    }
    
    void init()
    {
        V.clear();
        clr(add, 0);
        clr(Max, 0);
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while (T--)
        {
            init();
            V.pb(make_pair(0,-1));
            int n;
            scanf("%d", &n);
            for (int i = 0; i < n; i++)
            {
                scanf("%d%d%d%d%d", &N[i].l, &N[i].r, &N[i].a, &N[i].b, &N[i].c);
                V.pb(make_pair(2 * N[i].l , i));
                V.pb(make_pair(2 * N[i].r , i));
                V.pb(make_pair(2 * N[i].l + 1, -1));
                V.pb(make_pair(2 * N[i].r + 1, -1));
                N[i].l = N[i].r = -1;
            }
            int pos = 1;
            sort(V.begin(), V.end());
            for (int i = 0; i < V.size(); i++)
            {
                if (V[i].Y == -1)
                {
                    pos++;
                    continue;
                }
                if (N[V[i].Y].l == -1)
                    N[V[i].Y].l = pos;
                else N[V[i].Y].r = pos;
                if (i != V.size() - 1 && V[i].X == V[i+1].X) continue;
                pos++;
            }
            pos--;
            for (int i = 0; i < n; i++)
            {
                if (N[i].l - 1 >= 1) update(1, N[i].l - 1, N[i].c, 1, pos, 1);
                update(N[i].l, N[i].r, N[i].a, 1, pos, 1);
                if (N[i].r + 1 <= pos) update(N[i].r + 1, pos, N[i].b, 1, pos, 1);
            }
            printf("%I64d
    ", query(1, pos, 1, pos, 1));
        }
        return 0;
    }
    View Code

    剩下两题不会了= =,这场能升分得益于A题的错误贪心发现得早。。没造成太多罚时损失,遗憾是手速太慢没hack到人。B题知道做法,但是调线段树调了半天,还没注意到可以是实数,样例一直调不过,决定去刷下线段树专题,,补补线段树。

    2017-01-23 22:09:00

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  • 相关阅读:
    日期获取以及时间转化
    ddt 接口框架数据处理调用excel 处理
    ddt 测试用例UI运用
    动态验证码处理UI自动化获取处理
    Bug Report For .Net (zz.IS2120@BG57IV3)
    中关村翠湖科技园:高端产业聚集区 (zz.IS2120@BG57IV3.T752270541 .K)
    vc6,windows 7 x64 调试 (IS2120@BG57IV3)
    Excel c#Excel文件的操作[转载]
    NUnit学习 标签、方法 记录与说明
    Excel c#Excel工作进程的创建写 与Excel文件的保存[原创] (20100205 11:09)
  • 原文地址:https://www.cnblogs.com/scaugsh/p/6339179.html
Copyright © 2020-2023  润新知