贪心算法
资源配置,收益最大化
小Q的公司最近接到m个任务, 第i个任务需要xi的时间去完成, 难度等级为yi。
小Q拥有n台机器, 每台机器最长工作时间zi, 机器等级wi。
对于一个任务,它只能交由一台机器来完成, 如果安排给它的机器的最长工作时间小于任务需要的时间, 则不能完成,如果完成这个任务将获得200 * xi + 3 * yi收益。
对于一台机器,它一天只能完成一个任务, 如果它的机器等级小于安排给它的任务难度等级, 则不能完成。
小Q想在今天尽可能的去完成任务, 即完成的任务数量最大。如果有多种安排方案,小Q还想找到收益最大的那个方案。小Q需要你来帮助他计算一下。
输入描述:
输入包括N + M + 1行,
输入的第一行为两个正整数n和m(1 <= n, m <= 100000), 表示机器的数量和任务的数量。
接下来n行,每行两个整数zi和wi(0 < zi < 1000, 0 <= wi <= 100), 表示每台机器的最大工作时间和机器等级。
接下来的m行,每行两个整数xi和yi(0 < xi < 1000, 0 <= yi<= 100), 表示每个任务需要的完成时间和任务的难度等级。
输出描述:
输出两个整数, 分别表示最大能完成的任务数量和获取的收益。
示例1
输入:
1 2
100 3
100 2
100 1
输出
1 20006
#贪心算法,为了保证利益最大化,先完成时间最多的,所以根据时间将机器和任务进行从大到小的排序
class node():
def __init__(self,time,level):
self.time=time
self.level=level
#读取输入的第一行,机器数量和任务数量
n,m=map(int,input().split())
machines=[]
jobs=[]
#读取每台机器的最大工作时间和机器等级
for i in range(n):
time,level= map(int,input().split(' '))
machine = node(time,level)
machines.append(machine)
#读取每个任务的最大工作时间和工作等级
for i in range(m):
time,level= map(int,input().split(' '))
job = node(time,level)
jobs.append(machine)
#根据时间排序
machines.sort(key=lambda x:(x.time,x.level),reverse=True)
jobs.sort(key=lambda x:(x.time,x.level),reverse=True)
#收益和工作数量
profit=0
count=0
j=0#机器用完或者没有工作为止
levels=[0]*101
for i in range(m):
#两个限制条件,应该使用串行的判断条件
while j<n and machines[j].time>jobs[i].time:
#记录满足时间条件的机器
levels[machines[j].level]+=1
j+=1
for k in range(jobs[i].level,101):
#判断有没有满足的水平的机器
if(levels[k]):
count+=1
levels[k]-=1
profit+=200*jobs[i].time+3*jobs[i].level
break
print(count, end=' ')
print(profit)
字典序
字典序最小:从小到大排列
字典序最大:从大到小排列
链接:https://www.nowcoder.com/questionTerminal/21cbcf96d99d42a18e50553df27cd230
来源:牛客网
有一天,小易把1到n的所有排列按字典序排成一排。小易从中选出了一个排列,假设它是正数第Q个排列,小易希望你能回答他倒数第Q个排列是什么。
例如1到3的所有排列是:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
若小易选出的排列是1 2 3,则Q = 1,而你应该输出排列3 2 1
输入描述:
第一行数字n,表示排列长度
接下来一行n个数字,表示选出的排列
1 ≤ n ≤ 3000001 ≤ n ≤ 300000 1 \leq n \leq 3000001≤n≤300000 1≤n≤3000001≤n≤300000
输出描述:
一行n个数字,表示所求的排列
示例
输入:
3
1 2 3
输出
3 2 1
#通过分析可以看出来,位置相对称的两个排列,对应位数字之和为n+1,直接计算输出就行了
华为测试
1.通过一个空格进行分割,其中仅第一组的年与日包含星期几,请推算出第二组的年月日