zoukankan      html  css  js  c++  java
  • 贪心算法小结

    A

    题意:多个教室经过走廊搬桌子,不能共用已被占用的走廊(不相交可以同时搬运),每次需要十分钟,问最少需要的时间。

    思路:每次搬运都会覆盖一段走廊,会覆盖这段的点,找出所有点中覆盖次数最多的即是需要搬运的最大次数。

    B

    题意:O(-1)

    思路:O(-1)。

    C

    题意:有n头牛在一条线上,每头牛都会嚎叫,为了让所有牛都听见,嚎叫的声音等于离它最远牛的距离,问所有牛嚎叫的声音分贝是多少。

    思路:对所有牛按位置排序,分贝划过两头牛之间距离的次数之和便是答案,遍历即可。

    D

    题意:有n个人,每个人都有m张纸牌,所有的纸牌都在1~n*m之间并且不重复,每轮每个人拿出一张纸牌比较大小,最大的赢得这轮。给出你的m张纸牌大小,问你最小能赢多少轮。

    思路:你从最小开始出,对方先出一张比你大的,其他人从最小开始出,依次继续。当你再次出牌的时候找不到对手点数有比你大的,那么你后面都是赢。

    E

    题意:给你n种品牌交流机器,每种类型交流机器又有m种分支产品,现在让你从n种品牌中各选择一种,要求B/P最大,B为这选择的n种中b最小的,P则为选择的n种的价值和。

    思路:枚举所有出现的B,对每种产品的p进行从小到大排序,每次都选择这种产品中第一个大于B的。选取所有枚举情况的最优解即可。

    F

    题意:O(-1).

    思路:不对局部而对全程分析,你跟到最后一起到达终点的必是在你后出发而又最快到达终点的。

    G/H

    题意:O(-1)

    思路:两题类似。先对罚时从大到小排序,对于每门功课,从最后期限开始往前找(保证最优解),找到空位即可。

    I

    题意:给出海面上n个岛屿的坐标,给出你雷达扫描半径,问你最少要安装多少个雷达才可监控到所有的海上岛屿。

    思路:对每个岛屿分析可知,每个岛屿可被地面上一段[l,r]内的雷达扫射到,只要雷达安装到这段区域内便可监控到该岛屿。处理出所有的这些区间段,排序后从左到右扫一遍,覆盖区域选最左边的右端点值rbd,在rbd左边的相交区域选一个雷达即可。

    J

    题意:O(-1)

    思路:排序之后从左往右铺即可,要注意的一点是当木板很长很长的一种情况。

    K

    题意:O(-1).

    思路:黑书上的一道例题。因为钓鱼只能从左往右走,枚举所有情况:即只走到第i个(i输出1~n)。然后对于枚举的每种情况,选择鱼最多的池塘去钓鱼,这时候你可以想象成你能飞来飞去。

    L

    题意:有一颗n个节点n-1条边的树,每个节点有一个C[i]值,每到达一个节点time加1,到达这个节点的处罚是time*C[i],并且只有当父亲节点走完了才能走孩子节点。

    思路: 开始对C值进行排序,每次都找未标记的C值最大的节点,从该节点往前走到根节点都标记一下,后来证明这样是错的。

    因为每个节点受限制于父亲节点,正确的处理方法是利用fact[i]/num[i]进行贪心操作,fact[i]表示该节点集合的C值总和,num表示该集合的节点数。每次选取fact[i]/num[i]最大的,并将它归并与父亲集合,父亲num值加1。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 typedef long long lld;
     8 const int maxn=1024;
     9 int pre[maxn], next[maxn][maxn], ind[maxn],  visit[maxn], fact[maxn], num[maxn];
    10 int n, rt;
    11 
    12 int find()
    13 {
    14     double maxx=0, pos=-1;
    15     for(int i=1; i<=n; i++)
    16         if(!visit[i]&&i!=rt&&1.0*fact[i]/num[i]>maxx)
    17         {
    18             maxx=1.0*fact[i]/num[i];
    19             pos=i;
    20         }
    21     return pos;
    22 }
    23 
    24 void Union(int x, int y)
    25 {
    26     for(int i=1; i<=ind[x]; i++)
    27     {
    28         pre[ next[x][i] ]=y;
    29         next[y][++ind[y]]=next[x][i];
    30     }
    31     fact[y]+=fact[x];
    32     num[y]+=num[x];
    33 }
    34 
    35 void Solve()
    36 {
    37     int ans=0;
    38     for(int i=1; i<n; i++)
    39     {
    40         int id=find();
    41         if(id==-1) break;
    42         visit[id]=1;
    43         ans+=fact[id]*num[ pre[id]  ];
    44         Union(id,pre[id]);
    45     }
    46     cout << ans+fact[rt] <<endl;
    47 }
    48 
    49 int main()
    50 {
    51       while(cin >> n >> rt, n+rt)
    52       {
    53           memset(visit,0,sizeof(visit));
    54           memset(next,0,sizeof(next));
    55           memset(ind,0,sizeof(ind));
    56           for(int i=1; i<=n; i++)
    57           {
    58               scanf("%d",fact+i);
    59               num[i]=1;
    60           }
    61           for(int i=1; i<=n-1; i++)
    62           {
    63               int u, v;
    64               scanf("%d%d",&u,&v);
    65               pre[v]=u;
    66               next[u][++ind[u]]=v;
    67           }
    68           Solve();
    69       }
    70 }
    View Code

    M

    题意:O(-1)

    思路:从大到小,三个一组,所有组里面最小的之和即使答案。

  • 相关阅读:
    10-JS的函数学习
    Servlet(生命周期)
    09-js数组常用方法
    08-计算器案例
    07-js数组
    06-js的逻辑结构
    使用css设置三角形
    关于background-size 的一点小坑
    a 标签实现分享功能
    关于页面缩放时css错乱的处理方法---之一
  • 原文地址:https://www.cnblogs.com/kane0526/p/3235021.html
Copyright © 2011-2022 走看看