zoukankan      html  css  js  c++  java
  • Codeforces Round #413, rated, Div. 1 + Div. 2 C. Fountains(贪心 or 树状数组)

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

    题意:

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

    思路:

    首先想到分三种情况讨论,两个花园都用硬币,两个花园都用钻石,一个用钻石一个用硬币。

    大神的代码真的是很厉害,首先买不起直接省去,接下来先按照价格对花园排序,接下来这个for_max写得很强,记录了第i个之前最大的漂亮度。,接下来进行循环,i从0开始++,然后判断是否满足i<j,然后两座花园所需钱币数量小于目前有的钱币数量,如果满足不断使i++,这样做是满足贪心要求,你目前求得必然是在当前j的条件下最大的,最终求出答案。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<stack>
     7 #include<queue>
     8 #include<cmath>
     9 #include<map>
    10 using namespace std;
    11 
    12 const int maxn=100000+5;
    13 typedef pair<int,int> pll;
    14 
    15 int n,c,d;
    16 vector<pll> CC,DD;
    17 int for_max[maxn];
    18 
    19 int solve(vector<pll> z,int money)
    20 {
    21     int len=z.size();
    22     if(len<2)  return 0;
    23     int ans=0;
    24     sort(z.begin(),z.end());  //先按照价格排序
    25     for_max[0]=0;
    26     for(int i=0;i<len;i++)  for_max[i+1]=max(for_max[i],z[i].second); //预处理,计算出前i个当中最大的漂亮度
    27     int i=0;
    28     for(int j=len-1;j>=0;j--)
    29     {
    30         while(i<j && z[i].first+z[j].first<=money)  i++; //因为for_max[i]记录了前i-1个的最大漂亮度,所以只要没超过总价格,就可以一直加上去
    31         i=min(i,j);
    32         if(i>0)
    33             ans=max(ans,for_max[i]+z[j].second);
    34     }
    35     return ans;
    36 }
    37 
    38 int main()
    39 {
    40     //freopen("D:\input.txt","r",stdin);
    41     while(~scanf("%d%d%d",&n,&c,&d))
    42     {
    43         CC.clear(); DD.clear();
    44         int cc_max=0,dd_max=0;
    45         int ans=0;
    46         int b,p; char s[5];
    47         for(int i=0;i<n;i++)
    48         {
    49             scanf("%d%d%s",&b,&p,&s);
    50             if(s[0]=='C')
    51             {
    52                 if(p>c)  continue;  //买不起的直接省去
    53                 CC.push_back(make_pair(p,b));
    54                 cc_max=max(cc_max,b);
    55             }
    56             else
    57             {
    58                 if(p>d)  continue;
    59                 DD.push_back(make_pair(p,b));
    60                 dd_max=max(dd_max,b);
    61             }
    62         }
    63         if(cc_max!=0 && dd_max!=0)  ans=cc_max+dd_max;   //第一种情况
    64         ans=max(ans,solve(CC,c));   //两个都是硬币
    65         ans=max(ans,solve(DD,d));   //两个都是钻石
    66         printf("%d
    ",ans);
    67     }
    68   return 0;
    69 }

    另外,树状数组也是可以做的,可以参考http://blog.csdn.net/ssimple_y/article/details/71702915

  • 相关阅读:
    Android 使用ViewPager结合PhotoView开源组件实现网络图片在线浏览功能
    Android教程 -06 Activity的生命周期
    Android教程 -05 Android6.0权限的管理
    Android 设置ImageView宽度固定,其高度按比例缩放适应
    一技压身,天下行走
    解析P2P金融的业务安全
    Android Listview中Button按钮点击事件冲突解决办法
    Android 动态设置TextView的drawableLeft等属性
    Android教程 -04 启动其它Activity,静态工厂设计模式传递数据
    瞬息之间与时间之门
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6901282.html
Copyright © 2011-2022 走看看