zoukankan      html  css  js  c++  java
  • 【贪心+前缀】C. Fountains

    http://codeforces.com/contest/799/problem/C

    【题意】

    有n做花园,有人有c个硬币,d个钻石 (2 ≤ n ≤ 100 000, 0 ≤ c, d ≤ 100 000) ,每一个花园用三个维度描述(a,b,c),分别是美丽度,所花钱币个数,钱币种类,当然,钱币之间不能兑换,该人必须要建筑两座花园,如果可以,输出两座花园总的美丽度,否则输出0;

    【思路】

    首先,有三种分类:

    • 两座花园一座用钻石,一座用硬币
    • 两座花园都用钻石
    • 两座花园都用硬币

    注意两座花园只能同时都买,不能只买一座

    第一种情况比较简单,只要找出在两种分类中美丽度分别最大的即可

    第二种情况和第三种是类似的,我们只考虑第二种:

    首先,价格超过限度的直接省去,然后我们想知道价值和不超过限度的最大美丽度是多少。

    我们可以枚举一座花园的价值price1,然后找到另一座满足price2<=c-price1的美丽度最大的花园。

    一个很强的做法就是:

    按price从小到大排序,for_max数组记录前缀0~i的最大美丽度,只要price[i]满足<=c-price1,就可以i++,最后找到的美丽度一定是最大的。

    而且这样做只要一次for循环,price1从后向前枚举,price2的限界一定是增大的,所以只要不断在上一层循环的基础上增加就可以了~

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<cmath>
     6 #include<vector>
     7 #include<algorithm> 
     8 
     9 using namespace std;
    10 const int maxn=1e5+5;
    11 typedef pair<int,int> pii;
    12 vector<pii> CC,DD;
    13 int n,c,d;
    14 
    15 int Solve(vector<pii> z,int money)
    16 {
    17      int for_max[maxn];
    18      int sz=z.size();
    19      sort(z.begin(),z.end());
    20      for_max[0]=0;
    21      for(int i=1;i<=sz;i++)
    22      {
    23         for_max[i]=max(for_max[i-1],z[i-1].second);
    24     }
    25     int i=0;
    26     int ans=0;
    27     for(int k=sz-1;k>=0;k--)
    28     {
    29         while(i<k&&z[i].first+z[k].first<=money)
    30         {
    31                  i++;
    32          }
    33          i=min(i,k);
    34          if(i>0)
    35          {
    36              ans=max(ans,for_max[i]+z[k].second);
    37          }
    38          
    39     }
    40     return ans;
    41 }
    42 int main()
    43 {
    44      scanf("%d%d%d",&n,&c,&d);
    45      int p,b;
    46      int max_c=0,max_d=0;
    47      char tag[5];
    48      for(int i=0;i<n;i++)
    49      {
    50         scanf("%d%d%s",&b,&p,tag);
    51         if(tag[0]=='C')
    52         {
    53              if(p>c)
    54             {
    55                       continue;
    56             }
    57             CC.push_back(make_pair(p,b));
    58             max_c=max(max_c,b);       
    59           }
    60           else
    61           {
    62              if(p>d)
    63             {
    64                       continue;
    65             }
    66             DD.push_back(make_pair(p,b));
    67             max_d=max(max_d,b);
    68         }
    69     }
    70     int ans;
    71     if(max_c==0||max_d==0)
    72     {
    73         ans=0;
    74     }
    75     else
    76     {
    77         ans=max_c+max_d;
    78     }
    79     ans=max(ans,Solve(CC,c));
    80     ans=max(ans,Solve(DD,d));
    81     printf("%d
    ",ans);
    82      return 0;
    83 }
    贪心+前缀
  • 相关阅读:
    Python笔记 —— 使用open打开和操作txt文件
    Python笔记 —— 文件路径
    Python笔记 —— 四种容器(列表,元组,字典,集合)
    C++笔记 —— 异常
    C++笔记 —— map常用方法
    C++笔记 —— 在模板类中重载操作符
    C++笔记 —— vector常用方法
    C++笔记 —— 强制类型转换
    TCP连接三次握手四次挥手
    HashMap中自定义对象key,实现hashcode与equal
  • 原文地址:https://www.cnblogs.com/itcsl/p/6912472.html
Copyright © 2011-2022 走看看