类的调用和贪心思想

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

前言

真“可喜可贺”,今晚用面向对象完整的敲出来了两道题,而且是我之前看都不敢看的贪心,马上蓝桥杯要来了,这个时候肯定是要抓紧来查漏补缺一下。不知道有没有人跟我一样,之前感觉贪心很复杂的。

一、活动安排

链接:活动安排 - 题库 - 计蒜客 (jisuanke.com)

设有 nn 个活动的集合 E=\{1, 2, \cdots n\}E={1,2,⋯n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。

每个活动 ii 都有一个要求使用该资源的起始时间 s_isi​ 和一个结束时间 f_ifi​,且 s_i<f_isi​<fi​。如果选择了活动 ii,则它在时间区间 [s_i,f_i)[si​,fi​) 内占用资源。若区间 [s_i,f_i)[si​,fi​) 与区间 [s_j,f_j)[sj​,fj​) 不相交,则称活动 ii 与活动 jj 是相容的。也就是说,当 f_i \le s_jfi​≤sj​ 或 f_j \le s_ifj​≤si​时,活动 ii 与活动 jj 相容。

选择出由互相兼容的活动组成的最大集合。

输入格式

第一行一个整数 n(n \le 1000)n(n≤1000)。

接下来的 nn 行,每行两个整数 s_isi​ 和 f_ifi​,其中 0 < s_i < f_i < 20000<si​<fi​<2000。

输出格式

输出尽可能多的互相兼容的活动个数

这个的话应该是最基础的贪心思想的题了吧,除了找零钱那个半吊子贪心以外的。

这个题的主要步骤是先根据结束时间来排序,排完之后再根据相邻的两个活动的后一个的开始时间和前一个的结束时间相比较,如果前者大于等于后者,则两个活动能同时进行,反正则不能,依次得到局部最优解。

class act():
    def __init__(self,start,end):
        self.start=start
        self.end=end
n=int(input())
a=[1 for i in range(n)]
b=[]
for i in range(n):
    x,y=map(int,input().split())
    b.append(act(x,y))
    b.sort(key=lambda x:x.end)
k=0
for i in range(1,n):
    if b[i].start>=b[k].end:
        a[i]=1
        k=i
    else:
        a[i]=0
ans=0
for i in a:
    if i==1:
        ans+=1
print(ans)
#在这里用了标记列表

二,种树

链接:#10001. 「一本通 1.1 例 2」种树 - 题目 - LibreOJ (loj.ac)

题目描述

某条街被划为 nn 条路段,这 nn 条路段依次编号为 1\dots n1…n。每个路段最多可以种一棵树。现在居民们给出了 hh 组建议,每组建议包含三个整数 b,e,tb,e,t,表示居民希望在路段 bb 到 ee 之间至少要种 tt 棵树。这些建议所给路段的区间可以交叉。请问:如果要满足所有居民的建议,至少要种多少棵树。

输入格式

第一行为 nn,表示路段数。

第二行为 hh,表示建议数。

下面 hh 行描述一条建议:b, e, tb,e,t,用一个空格分隔。

输出格式

输出只有一个数,为满足所有居民的建议,所需要种树的最少数量。

这个也是经典模板题,区间选点,可是我之前都不敢看这题,这题也是根据区间的末尾进行排序,然后尽量把树种到两个区间的交集中,就是第一个区间的后半部分,直到此区间和后一个区间没有交集,再去找下一个区间和后面的交集。

 

class shu():
    def __init__(self,start,end,w):
        self.start=start
        self.end=end
        self.w=w
a=int(input())
m=int(input())
c=[]
book=[0]*30005
for i in range(m):
    start,end,w=map(int,input().split())
    c.append(shu(start,end,w))
c.sort(key=lambda x:x.end)
for i in range(m):
    t=0
    for j in range(c[i].start,c[i].end+1):
        if book[j]==1:
            t+=1#查找之前种的树是否有再本区间
    if t<c[i].w:
        k=c[i].w-t
        p=c[i].end
        while(k>0):
            if (book[p]==0):
                book[p]=1#新的区间的树,都要从最后开始种
                k-=1
            p-=1
ans=0
for i in range(a+1):
    if book[i]==1:
        ans+=1
print(ans)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值