【算法题】机试指南-贪心篇

本文仅供个人学习使用,免费分享。每日更新,建议关注收藏!
目前[机试指南]本系列已经达到字数10w+,所以按原每个章节拆开发布,点击目录跳转。

本站友情链接:

  1. c/c++算法题指南
    严书代码
    c/c++大复习1
    c/c++大复习2
  2. python算法题指南
    牛客华为机试103精华
    python输入输出大全
    python语法
    PAT甲级真题刷题笔记 共179道
  3. python官方文档
    python官方文档
  4. 机试指南系列
    基础篇
    贪心篇
    递归分治搜索篇
    数据结构进阶篇(树/图/优先队列)
    数学问题篇
    动态规划篇
    STL篇

贪心

用于最优化问题,总是选择当前最优策略,能得到局部最优解,往往能得到全局较优解,但不保证收敛到全剧最优解
【但是】对于具备无后效行的问题,贪心保证一定收敛到全剧最优解
无后效行是指:某个状态的以前的过程不会影响到以后,只和当前状态有关。
无法通过贪心策略求解最优化的请见动态规划章节

简单贪心

这种问题只需要选择合适的贪心策略。

鸡兔同笼问题
http://t.cn/E9ewERU 答案略

这种思想就是,计算最多动物数时优先考虑脚少的鸡,计算最少动物数时优先考虑脚多的兔,直到脚的数目不能构成兔子再选鸡;

https://www.lintcode.com/problem/149/
这种贪心有点像dp,需要打表

 def max_profit(self, prices: List[int]) -> int:
        # write your code here
        min_price=[prices[0]]#i下标表示 i天及之前的最小价格
        profit=0
        for i in range(1,len(prices)):
            if(min_price[i-1]<prices[i]):
                min_price.append(min_price[i-1])
            else:
                min_price.append(prices[i])
            profit=max(profit,prices[i]-min_price[i])
        print(min_price)
        return profit

区间贪心

有多个不同区间且它们有可能重叠,如何选择最多两两互不相交的区间。

例题7.4 今年暑假不AC http://acm.hdu.edu.cn/showproblem.php?pid=2037
思路:选择结束早且仍能观看的节目,如法炮制。

习题7.2 To Fill or Not to Fill(清华大学复试上机题) http://dwz.date/b2tj
目标是找最便宜的花销是多少(保留2位数),如果到达不了,还要输出"The maximum travel distance = X" ,X是能跑的最大长度(保留2位数)
实在是不知道这个最便宜花销是怎么算出来的 也没有一个官方解析 ,能跑到的X这部分代码没问题

import sys
'''
def calculate(gas_stations,prices_gas,d,capacity,gasunit_run):
    sum=0
    for item in prices_gas:
        need=min(capacity,(d-prices_gas[1])/gasunit_run)
        sum+=need*prices_gas[0]
        d-=need*gasunit_run
'''
for line in sys.stdin:
    a = line.split()
    capacity=int(a[0])
    d=float(a[1])
    gasunit_run=float(a[2])
    number=int(a[3])
    gas_stations=[]
    now_d=0
    now_c=0
    sum=0
    flag=0 #1 抵达
    for i in range(number):
        temp=input().split()
        gas_stations.append([float(temp[0]),int(temp[1])] )
    gas_stations=sorted(gas_stations,key=lambda x:(x[1],x[0]))
    print(gas_stations)
    prices_gas=sorted(gas_stations,key=lambda x:x[0])
    print(prices_gas)
    for j in range(len(gas_stations)):
        print('现在在',now_d,'油剩',now_c,'已经花了',sum)
        
        if(j==len(gas_stations)-1):break
        if(gas_stations[j+1][0]<gas_stations[j][0]):
            print('#后面的油便宜,只买到够到下一个加油站')
            
            if(now_d==gas_stations[j][1]):
                print('到站买油')
                need=(gas_stations[j+1][1]-gas_stations[j][1])/gasunit_run
                if(now_c>=need):
                    print('够用,不买了')
                    now_c-=need
                    now_d=gas_stations[j+1][1]
                else:
                    print('不够用,买')
                    sum+= (need-now_c)*gas_stations[j][0]
                    now_c=need
                    now_d=gas_stations[j+1][1]
                    now_c=0
            else: 
                print('到不了下一站,停住')
                flag=0
                break
        else:
            print('#后面的油贵,看看够不够到下下个站,够的话就不买了')
            max_cango=now_d+now_c*gasunit_run
            
            if(now_d==gas_stations[j][1]):
                
                print('到站买油')
                sum+= (capacity-now_c)*gas_stations[j][0] #加满
                now_c=capacity
                now_d=gas_stations[j+1][1]#开到下一个加油站
                now_c-=(gas_stations[j+1][1]-gas_stations[j][1])/gasunit_run #耗油
            else: 
                print('到不了下一站,停住')
                flag=0
                break
    print('先买满')
    if(now_d==gas_stations[-1][1] ):
        print('到站买油')
        need=(d-now_d)/gasunit_run
        now_c+=need
        if(now_c>capacity):
            print('到不了终点')
            sum+= (need-now_c+capacity)*gas_stations[-1][0]
            now_d+=capacity*gasunit_run
            now_c=0
        else:
            sum+= need*gas_stations[-1][0] #加到到达目的地的量即可
            now_d=d
            now_c=0
    else: 
        print('到不了下一站,停住')
        flag=0
        
    if(now_d>=d):
        flag=1
        print('finish!')
        #sum=calculate(gas_stations,prices_gas,d,capacity,gasunit_run)#重新计算
    if(flag==0):
        print("The maximum travel distance = "+str(now_d))
    else:
        print(sum)
                
    
import sys
'''
def calculate(gas_stations,prices_gas,d,capacity,gasunit_run):
    sum=0
    for item in prices_gas:
        need=min(capacity,(d-prices_gas[1])/gasunit_run)
        sum+=need*prices_gas[0]
        d-=need*gasunit_run
'''
for line in sys.stdin:
    a = line.split()
    capacity=int(a[0])
    d=float(a[1])
    gasunit_run=float(a[2])
    number=int(a[3])
    gas_stations=[]
    now_d=0
    now_c=0
    sum=0
    flag=0 #1 抵达
    for i in range(number):
        temp=input().split()
        gas_stations.append([float(temp[0]),int(temp[1])] )
    gas_stations=sorted(gas_stations,key=lambda x:(x[1],x[0]))
    #print(gas_stations)
    prices_gas=sorted(gas_stations,key=lambda x:x[0])
    #print(prices_gas)
    for j in range(len(gas_stations)):
        #print('现在在',now_d,'油剩',now_c,'已经花了',sum)
        
        if(j==len(gas_stations)-1):break
        if(gas_stations[j+1][0]<gas_stations[j][0]):
            #print('#后面的油便宜,只买到够到下一个加油站')
            
            if(now_d==gas_stations[j][1]):
                #print('到站买油')
                need=(gas_stations[j+1][1]-gas_stations[j][1])/gasunit_run
                if(now_c>=need):
                    #print('够用,不买了')
                    now_c-=need
                    now_d=gas_stations[j+1][1]
                else:
                    #print('不够用,买')
                    sum+= (need-now_c)*gas_stations[j][0]
                    now_c=need
                    now_d=gas_stations[j+1][1]
                    now_c=0
            else: 
                #print('到不了下一站,停住')
                flag=0
                break
        else:
            #print('#后面的油贵,看看够不够到下下个站,够的话就不买了')
            max_cango=now_d+now_c*gasunit_run
            
            if(now_d==gas_stations[j][1]):
                
                #print('到站买油')
                sum+= (capacity-now_c)*gas_stations[j][0] #加满
                now_c=capacity
                now_d=gas_stations[j+1][1]#开到下一个加油站
                now_c-=(gas_stations[j+1][1]-gas_stations[j][1])/gasunit_run #耗油
            else: 
                #print('到不了下一站,停住')
                flag=0
                break
    #print('先买满')
    if(now_d==gas_stations[-1][1] ):
        #print('到站买油')
        need=(d-now_d)/gasunit_run
        now_c+=need
        if(now_c>capacity):
            #print('到不了终点')
            sum+= (need-now_c+capacity)*gas_stations[-1][0]
            now_d+=capacity*gasunit_run
            now_c=0
        else:
            sum+= need*gas_stations[-1][0] #加到到达目的地的量即可
            now_d=d
            now_c=0
    else: 
        #print('到不了下一站,停住')
        flag=0
        
    if(now_d>=d):
        flag=1
        #print('finish!')
        #sum=calculate(gas_stations,prices_gas,d,capacity,gasunit_run)#重新计算
    if(flag==0):
        print("The maximum travel distance = {:.2f}".format(now_d))
    else:
        print('{:.2f}'.format(sum))
                
    
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值