贪心问题初步

简介: 贪心问题初步

首选理解一下贪心问题:贪心问题是一种从局部最优得到全局最优的问题,意思是立足于一点,从这点出发开始想最优解,一步步得出最终解。

通过上面口语化的描述,可见一个贪心问题对关键就是如何立足于一点寻找最优解,这里的关键就是最优解的度量方法。

下面是一个贪心问题的通用流程:

proceduce Greedy(A,n){//A中包含n个输入

解向量solution初始为空

从1到n

按照最优度量选出A中一个输入x  //**最优度量**

如果可以加入solution则加入   //**如何判断**

重复上述过程

返回解向量结果


由上可见,如果把握好最优度量标准和判断条件,那么问题也就基本解决了,下面来看实战:


1.基础简单贪心问题


背包问题: 已知n种物品和一个可以容纳重量为M的背包,物品重量收益用wi和pi表示,试求怎样将物品放入背包总收益最大。


分析:很显然这个问题很容易让我们想到买商品时的单价,如果用wi/pi表示单位收益再非增排序,依次选取放入背包即可。 其中wi/pi就是度量标准,判断条件只要重量和小于M就可以继续加入,直到相等。


2.区间贪心问题


看电视 :

暑假到了,小明终于可以开心的看电视了。但是小明喜欢的节目太多了,他希望尽量多的看到完整的节目。

现在他把他喜欢的电视节目的转播时间表给你,你能帮他合理安排吗?

输入

输入包含多组测试数据。每组输入的第一行是一个整数n(n<=100),表示小明喜欢的节目的总数。

接下来n行,每行输入两个整数si和ei(1<=i<=n),表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。

当n=0时,输入结束。

输出

对于每组输入,输出能完整看到的电视节目的个数。


分析:上面的问题明显相当于给定一堆(a,b)的区间,叫我们挑选出不相交的最多区间数,这就是典型的区间贪心问题。首先如果两个区间大包小,我们肯定选择小的那个;如果两个区间相交,是不是可以把其中一个区间视为两部分,一部分是单独的,另一个部分是相交部分,单独的部分不影响,相交部分又转化为大包小问题,大包小取小,实质就取了被划分的那个区间。

根据上述思路,我们可以从左端点开始,也可以从右端点开始选取,然后贯彻上面那个思路收集符合条件的区间。

#include<algorithm> 
using namespace std;
const int maxn=100;
int n=1,sum;
struct tv{
  int a,b;
  bool operator<(const tv &c)const{
  if(c.b==b)return a>c.a;    
  return b<c.b;
  }
}T[100];
int main(){
  while(scanf("%d",&n),n!=0){
  sum=1;
  for(int i=0;i<n;i++){
  scanf("%d %d",&T[i].a,&T[i].b);
  }
  sort(T,T+n); //从右端点开始,从小到大排序
  int tag=0;
  for(int j=1;j<n;j++){
  if(T[tag].b<=T[j].a){  //找不相交点(主要有相交就取前一个)
    sum++;
    tag=j;
  }
  }
  printf("%d\n",sum);
}
  return 0;
}


此外这个问题还有一些变种,值得注意,如区间选点问题,区间覆盖问题。


3.综合应用


汽车加油问题: 你要从杭州开车到目的地,整条路线是一个数轴,你在数轴上的0点,目的地在距离0点为D米,你的车油罐的容量为C,每单位油可以行驶Davg 米,在路线上有n个加油站,每个加油站在位置为di处,单价是pi, 问你,从0点出发开到目的地所需要的最小花费是多少,若开不到目的地,输出最远可以到达的地方,油箱一开始为空。


分析:该问题的起点就在原点,如果此处没有加油站,肯定无法到达,如果有,立足于此加油站则思考下一个问题

如果能找满油最大行程到距离该加油站最近的价格更低的加油站,只加够到那里的油

如果没有则找最大行程内价格最低的油加满油到那

如果一个最大行程里没有加油站,凉凉,无法到达

#include<iostream>
#include<algorithm> 
using namespace std;
const int maxn=501;
struct station{
  double d,p;
  bool operator<(const station &a)const{
  if(a.d==d)return p<a.p;
  return d<a.d;
  } 
}T[maxn];
int n; 
double D,Davg,C,M,sum=0;
int main(){
  scanf("%lf%lf%lf%d",&C,&D,&Davg,&n);
  for(int i=0;i<n;i++){
  scanf("%lf%lf",&T[i].p,&T[i].d);}
  sort(T,T+n);   //           输入加油站并按距离出发点从小到大排序 
  M=C*Davg;
  if(T[0].d!=0)  //          如果出发点没有加油站 
  printf("The maximum travel distance = %.2f",0.00);
  else{
    double nowtank,need,minprice;
    int now=0,then,flag=0;
    T[n].d=D;T[n].p=0;
    while(now<n){
      then=-1;
      minprice=T[now+1].p;
    for(int i=now+1;(T[i].d-T[now].p)<=M&&i<=n;i++)
    { 
      if(T[i].p<=minprice){
      then=i;
   minprice=T[i].p;} 
      if(T[i].p<T[now].p)
      break;
    }
    if(then==-1) break;                          //第三种情况处理 
    need=(T[then].d-T[now].d)/Davg;
    if(minprice<T[now].p){ 
                                               //第一种情况处理 
      if(need<=nowtank)
      nowtank-=need;
      else{                                              
      sum+=(need-nowtank)*T[now].p;
      nowtank=0;
     }  
    }
      else{                                 //第二种情况处理       
      sum+=(C-nowtank)*T[now].p;
      nowtank=C-need;
    }
    now=then;flag=0; 
    }
   if(now==n)
  printf("%.2f\n",sum);
  else
  printf("The maximum travel distance = %.2f",T[now].d+M);
  }  
  return 0;
}
相关文章
|
消息中间件 JavaScript 小程序
用 Copliot 帮你搞定 Java 样板代码
用 Copliot 帮你搞定 Java 样板代码
|
存储 设计模式 缓存
DDD领域驱动设计实战-分层架构及代码目录结构(下)
DDD领域驱动设计实战-分层架构及代码目录结构
1589 0
DDD领域驱动设计实战-分层架构及代码目录结构(下)
|
存储 负载均衡 NoSQL
12306 的架构也太 牛X 了吧!
每到节假日期间,一二线城市返乡、外出游玩的人们几乎都面临着一个问题:抢火车票! 虽然现在大多数情况下都能订到票,但是放票瞬间即无票的场景,相信大家都深有体会。尤其是春节期间,大家不仅使用12306,还会考虑“智行”和其他的抢票软件,全国上下几亿人在这段时间都在抢票。
12306 的架构也太 牛X 了吧!
|
缓存 NoSQL 中间件
分布式事务之本地消息表解决方案(跨地区转账实际案例)
分布式事务之本地消息表解决方案(跨地区转账实际案例)
|
JSON 数据格式
将Object类对象转为对应实体类对象
将Object类对象转为对应实体类对象
|
监控 搜索推荐 算法
电商数据分析常用业务指标整理(共72个)
电商数据分析常用业务指标整理(共72个)
|
JSON fastjson 数据格式
利用fastjson对json转map的操作
String str = "{\"0\":\"zhangsan\",\"1\":\"lisi\",\"2\":\"wangwu\",\"3\":\"maliu\"}"; //第一种方式 Map maps = (Map)JSON.
11546 1
|
SQL 存储 JSON
Hive解析Json数组超全讲解(二)
在Hive中会有很多数据是用Json格式来存储的,如开发人员对APP上的页面进行埋点时,会将多个字段存放在一个json数组中,因此数据平台调用数据时,要对埋点数据进行解析。接下来就聊聊Hive中是如何解析json数据的。
1215 0
|
人工智能 算法 IDE
GitHub Copilot支持 IntelliJ IDEA啦,插件装起来!
GitHub Copilot支持 IntelliJ IDEA啦,插件装起来!
1990 0
GitHub Copilot支持 IntelliJ IDEA啦,插件装起来!
|
Java 关系型数据库 MySQL
MyBatis逆向工程
MyBatis逆向工程
216 0