zoukankan      html  css  js  c++  java
  • codeforces 799C Fountains

    C. Fountains
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Arkady plays Gardenscapes a lot. Arkady wants to build two new fountains. There are n available fountains, for each fountain its beauty and cost are known. There are two types of money in the game: coins and diamonds, so each fountain cost can be either in coins or diamonds. No money changes between the types are allowed.

    Help Arkady to find two fountains with maximum total beauty so that he can buy both at the same time.

    Input

    The first line contains three integers nc and d (2 ≤ n ≤ 100 000, 0 ≤ c, d ≤ 100 000) — the number of fountains, the number of coins and diamonds Arkady has.

    The next n lines describe fountains. Each of these lines contain two integers bi and pi (1 ≤ bi, pi ≤ 100 000) — the beauty and the cost of the i-th fountain, and then a letter "C" or "D", describing in which type of money is the cost of fountain i: in coins or in diamonds, respectively.

    Output

    Print the maximum total beauty of exactly two fountains Arkady can build. If he can't build two fountains, print 0.

    Examples
    input
    Copy
    3 7 6
    10 8 C
    4 3 C
    5 6 D
    output
    Copy
    9
    input
    Copy
    2 4 5
    2 5 C
    2 1 D
    output
    Copy
    0
    input
    Copy
    3 10 10
    5 5 C
    5 5 C
    10 11 D
    output
    Copy
    10
    Note

    In the first example Arkady should build the second fountain with beauty 4, which costs 3 coins. The first fountain he can't build because he don't have enough coins. Also Arkady should build the third fountain with beauty 5 which costs 6 diamonds. Thus the total beauty of built fountains is 9.

    In the second example there are two fountains, but Arkady can't build both of them, because he needs 5 coins for the first fountain, and Arkady has only 4 coins.

    题意:你有两种货币 C和D 可以买属性为C和D的货物,每种货物有他的beauty值,你现在有若干货币,需要你去买货物C和D得到最大的beauty值

    题解:这题理论上来说用n2暴力会T,emmmm但是实际上我们每次取到最大值后break一下的话,可以在1700ms的极限时间跑过去,正解应该是按照beauty值排序后线段树RMQ取区间最值

    暴力代码如下:

    #include <map>
    #include <set>
    #include <cmath>
    #include <ctime>
    #include <stack>
    #include <queue>
    #include <cstdio>
    #include <cctype>
    #include <bitset>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    #define fuck(x) cout<<"["<<x<<"]";
    #define FIN freopen("input.txt","r",stdin);
    #define FOUT freopen("output.txt","w+",stdout);
    //#pragma comment(linker, "/STACK:102400000,102400000")
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> PII;
    const int maxn = 1e5+5;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9+7;
    struct node{
        int p,c;
        bool operator < (const node &u) const{
            return p>u.p;
        }
    }a[maxn],b[maxn];
    int ta,tb;
    char ch[5];
    int u,v;
    int main(){
    #ifndef ONLINE_JUDGE
        FIN
    #endif
        int n,c,d;
        cin>>n>>c>>d;
        ta=tb=0;
        for(int i=0;i<n;i++){
            cin>>u>>v>>ch;
            if(ch[0]=='C'){
                a[ta].p=u;
                a[ta++].c=v;
            }else{
                b[tb].p=u;
                b[tb++].c=v;
            }
        }
        sort(a,a+ta);
        sort(b,b+tb);
        int ans=0;
        int pa=0,pb=0;
        for(int i=0;i<ta;i++){
            if(a[i].c<=c){
                pa=a[i].p;
                break;
            }
        }
        for(int i=0;i<tb;i++){
            if(b[i].c<=d){
                pb=b[i].p;
                break;
            }
        }
        if(pa&&pb) ans=max(ans,pa+pb);
        for(int i=0;i<ta;i++){
            for(int j=i+1;j<ta;j++){
                if(a[i].c+a[j].c<=c){
                    ans=max(ans,a[i].p+a[j].p);
                    break;
                }
            }
        }
        for(int i=0;i<tb;i++){
            for(int j=i+1;j<tb;j++){
                if(b[i].c+b[j].c<=d){
                    ans=max(ans,b[i].p+b[j].p);
                    break;
                }
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code

    日天学长写的RMQ代码如下:

    #include <bits/stdc++.h>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define x first
    #define y second
    #define rep(i,a,b) for(int i=a;i<b;++i)
    #define per(i,a,b) for(int i=a-1;i>=b;--i)
    #define fuck(x) cout<<'['<<#x<<' '<<(x)<<']'
    #define eps 1e-12
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef vector<int> VI;
    typedef pair<int, int> PII;
    const int mod = 998244353;
    
    const int INF = 0x3f3f3f3f;
    const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
    const int MX = 1e5 + 5;
    
    int v[MX], w[MX];
    char t[MX][2];
    
    PII p1[MX], p2[MX];
    int sz1, sz2;
    
    int solve1(int a, int b) {
        int mx1 = 0, mx2 = 0;
        for(int i = 1; i <= sz1; i++) {
            if(p1[i].x <= a) mx1 = max(mx1, p1[i].y);
        }
        for(int i = 1; i <= sz2; i++) {
            if(p2[i].x <= b) mx2 = max(mx2, p2[i].y);
        }
        return (mx1 > 0 && mx2 > 0) ? (mx1 + mx2) : 0;
    }
    int dp[MX][30];
    void ST(int n) {
        for (int i = 1; i <= n; i++) dp[i][0] = v[i];
        for (int j = 1; (1 << j) <= n; j++) {
            for (int i = 1; i + (1 << j) - 1 <= n; i++) {
                int a = dp[i][j - 1] , b = dp[i + (1 << (j - 1))][j - 1];
                dp[i][j] = max(a, b);
            }
        }
    }
    int RMQ(int l, int r) {
        if(l>r) return 0;
        int k = 0;
        while ((1 << (k + 1)) <= r - l + 1) k++;
        int a = dp[l][k], b = dp[r - (1 << k) + 1][k];
        return max(a, b);
    }
    int solve2(PII p[], int sz, int m) {
        if(sz <= 1) return 0;
        int ret =  0;
        sort(p + 1, p + sz + 1);
        rep(i, 1, sz + 1) w[i] = p[i].x;
        rep(i, 1, sz + 1) v[i] = p[i].y;
        rep(i, 2, sz + 1) assert(w[i] >= w[i - 1]);
        ST(sz);
        for(int i = 1, j = sz; i <= sz; i++) {
            while(w[i] + w[j] > m && j > i) j--;
            if(i < j) ret = max(ret, v[i] + RMQ(i + 1, j));
        }
        return ret;
    }
    
    int main() {
    #ifdef local
        freopen("in.txt", "r", stdin);
    #endif // local
    
        int n, a, b; cin >> n >> a >> b;
        rep(i, 1, n + 1) scanf("%d%d%s", &v[i], &w[i], t[i]);
        rep(i, 1, n + 1) {
            if(t[i][0] == 'C') p1[++sz1] = PII(w[i], v[i]);
            else p2[++sz2] = PII(w[i], v[i]);
        }
        int ans=solve1(a,b);
        ans=max(ans,solve2(p1,sz1,a));
        ans=max(ans,solve2(p2,sz2,b));
        cout<<ans<<endl;
    #ifdef local
        cout << "time cost:" << clock() << "ms" << endl;
    #endif // local
        return 0;
    }
    View Code
    每一个不曾刷题的日子 都是对生命的辜负 从弱小到强大,需要一段时间的沉淀,就是现在了 ~buerdepepeqi
  • 相关阅读:
    Hibernate实体类注解
    Struts2注解详解
    Spring注解大全
    Maven依赖机制
    Maven启动代理服务器
    SSH整合
    二进制求和 —— 从复杂方法到简单方法
    最大子序和 —— 动态规划解法
    括号匹配问题 —— Deque双端队列解法
    常见面试题 —— 两数之和(拒绝暴利法)
  • 原文地址:https://www.cnblogs.com/buerdepepeqi/p/9496427.html
Copyright © 2011-2022 走看看