Article catalog
Greedy Algorithm
Resource allocation, maximizing revenue
Xiaoq's company recently received m tasks, the i task needs xi time to complete, and the difficulty level is yi.
Xiaoq has n machines, the longest working time of each machine is zi, and the machine level is wi.
For a task, it can only be completed by one machine. If the maximum working time of the machine assigned to it is less than the time required by the task, it cannot be completed. If the task is completed, it will gain 200 * xi + 3 * yi.
For a machine, it can only complete one task a day. If its machine level is lower than the task difficulty level assigned to it, it cannot complete.
Xiaoq wants to finish as many tasks as possible today, that is to say, the number of tasks completed is the largest. If there are multiple arrangements, xiaoq also wants to find the one with the most profit. Xiaoq needs you to help him calculate.
Enter a description:
The input includes N + M + 1 lines,
The first input line is two positive integers n and m (1 < = n, m < = 100000), indicating the number of machines and tasks.
Next n lines, each line has two integers zi and wi (0 < zi < 1000, 0 < = wi < = 100), indicating the maximum working time and machine level of each machine.
The next m lines, two integers xi and Yi (0 < xi < 1000, 0 < = Yi < = 100) in each line, indicate the completion time and difficulty level of each task.
Output Description:
Output two integers, representing the maximum number of tasks that can be completed and the revenue obtained.
Example 1
Input:
1 2
100 3
100 2
100 1
output
1 20006
#Greedy algorithm, in order to ensure the maximization of benefits, completes the most time first, so sorts machines and tasks from large to small according to time class node(): def __init__(self,time,level): self.time=time self.level=level #Read the first line of input, number of machines and number of tasks n,m=map(int,input().split()) machines=[] jobs=[] #Read the maximum working time and machine level of each machine for i in range(n): time,level= map(int,input().split(' ')) machine = node(time,level) machines.append(machine) #Read the maximum working time and working level of each task for i in range(m): time,level= map(int,input().split(' ')) job = node(time,level) jobs.append(machine) #Sort by time machines.sort(key=lambda x:(x.time,x.level),reverse=True) jobs.sort(key=lambda x:(x.time,x.level),reverse=True) #Revenue and number of jobs profit=0 count=0 j=0#Until the machine runs out or does not work levels=[0]*101 for i in range(m): #Two restrictions, the serial judgment condition should be used while j<n and machines[j].time>jobs[i].time: #Record machines that meet time conditions levels[machines[j].level]+=1 j+=1 for k in range(jobs[i].level,101): #A machine that judges whether there is a level of satisfaction if(levels[k]): count+=1 levels[k]-=1 profit+=200*jobs[i].time+3*jobs[i].level break print(count, end=' ') print(profit)
Dictionary order
Dictionary order minimum: from small to large
Dictionary order: from large to small
Link: https://www.nowcoder.com/questionTerminal/21cbcf96d99d42a18e50553df27cd230
Source: niuke.com
One day, Xiaoyi put all the permutations from 1 to n in a dictionary order. Xiaoyi chooses a permutation from it. Suppose it is the Q permutation of positive number. Xiaoyi hopes you can answer what the Q permutation of reciprocal number is.
For example, all permutations from 1 to 3 are:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
If Xiaoyi chooses 1 2 3, then Q = 1, and you should output 3 2 1
Enter a description:
The number n in the first row indicates the arrangement length
Next n numbers in a row indicate the selected arrangement
1≤n≤3000001≤n≤3000001 \leq n \leq 3000001≤n≤3000001≤n≤3000001≤n≤300000
Output Description:
A row of n numbers representing the desired arrangement
Example
Input:
3
1 2 3
output
3 2 1
#It can be seen from the analysis that the two permutations of position are relatively symmetric, and the sum of corresponding digits is n+1, so the output can be calculated directly
Huawei test
1. Divide by a space. Only the year and day of the first group contain the day of the week. Please calculate the day of the year and the day of the second group.
a = input().split('|') begin = list(map(int, a[0].split())) end = list(map(int, a[1].split())) # Count the days and divide by 7 year = end[0] - begin[0] mounth = end[1] - end[1] mounths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] weeks = [1, 2, 3, 4, 5, 6, 7] day = [0, 0] # Calculate the date separately as the day of this year if ((begin[0] % 4 == 0 and begin[0] % 100 != 0) or begin[0] % 400 == 0): mounths[1] = 29 for i in range(begin[1]-1): day[0] += mounths[i] day[0] += begin[2] # Calculate the days of end in the year if ((end[0] % 4 == 0 and end[0] % 100 != 0) or end[0] % 400 == 0): mounths[1] = 29 else: mounths[1] = 28 for i in range(end[1]-1): day[1] += mounths[i] day[1] += end[2] if year == 0: days = day[1] - day[0] else: days = 0 for i in range(begin[0], end[0]): if ((i % 4 == 0 and i % 100 != 0) or i % 400 == 0): days += 366 else: days += 365 days = days - day[0] + day[1] # Calculate leap year # Get the difference between two dates print(days) result = (days % 7 + begin[3]) % 7 if(result==0): result=7 print(result)
2. There are several fixed position street lights on a road, which need to illuminate all bus stops on the road; now give the location serial number of all bus stops and roads on the road, and the bus stops and street lights are arranged on the road according to the location serial number.
Calculate the brightness of the street light to illuminate all the bus stops on the road,
a = list(map(int, input().split(','))) b = list(map(int, input().split(','))) print(a, b) a.sort() b.sort() # Find the maximum of several values minnums = [] # Calculation of intermediate position for i in range(len(a)): minnum = 10000 for j in range(len(b)): if (abs(a[i] - b[j]) < minnum): minnum = abs(a[i] - b[j]) minnums.append(minnum) print(minnums) result = max(minnums) print(result)
3. The owner of the rental house plans to buy a batch of new books, selects n books with the same price as alternatives, and sends a batch of questionnaires to the vip readers. The mobile phone goes to the list of books that each reader wants to read. In order to save the purchase cost, the owner decides to make sure that each vip reader has at least one favorite book in the purchase list to minimize the purchase cost. Output the minimum number of purchased books
Input example
5
3
1 2 3 4 5
1 2
2
3 4
vivo advance approval
Prototype topic: dynamic planning + binary search
Title:
You will get K eggs and can use a building with N floors from 1 to N.
Every egg has the same function. If an egg breaks, you can't drop it.
You know that there is floor F. any egg falling from a floor higher than f will be broken, and the egg falling from a floor f or a floor lower than f will not be broken.
Each time you move, you can take an egg (if you have a complete egg) and drop it from any floor X (meet 1 < = X < = n).
Your goal is to know exactly what the value of F is.
No matter what the initial value of F is, how many times do you determine the minimum movement of the value of F?
Example:
Input: K = 1, N = 2
Output: 2
Explanation:
The eggs fell from the first floor. If it breaks, we know F = 0.
Otherwise, the eggs fall off the second floor. If it breaks, we know F = 1.
If it's not broken, then we know F = 2.
So in the worst case we need to move twice to determine what F is.
Idea: after the number of eggs and the floor are determined, the minimum number of movements will also be determined, so the number of k,n corresponding to the number of dynamic planning can be obtained.
1. There are two cases of dropping eggs from floor X: broken and not broken. If broken, the next step is f(k-1,x-1). If not broken, f(k,n-x). Therefore, the minimum number of movements needed to find the critical floor is f(k,n)=max{fx(k-1,x-1),fx(k,n-x)}
2. It is known that f(k,n) should be the minimum value of all cases, that is, f(k,n)=min{f1(),f2() fn()}
Time complexity: O(kn^2)
class Solution: def superEggDrop(self, k: int, n: int) -> int: def parse(k, n): if n == 1: # If there is only one layer, no matter how many eggs there are, just try it once return 1 elif n == 0: return 0 elif k == 1: # If there is only one egg, it can only be tested layer by layer return n elif (k, n) in table: return table[(k, n)] f = float('inf') # Define an infinite number as the initial condition for x in range(1, n + 1): # Drop the eggs on layer x, starting with layer 1 fx = 1 + max(parse(k - 1, x - 1), parse(k, n - x)) f = min(f, fx) table[(k, n)] = f return f table = {} # Memory is counted return parse(k, n)
Optimization scheme: dynamic planning + binary search
The observation shows that fx(k-1,x-1) increases monotonically with the increase of X, fx(k,n-x) decreases monotonically with the increase of X, so we can find out the worst case by binary search. To find the minimum value code:
for x in range(1, n + 1): # Drop the eggs on layer x, starting with layer 1 fx = 1 + max(parse(k - 1, x - 1), parse(k, n - x)) f = min(f, fx)
Change to:
while lp <= rp: mid = lp + (rp-lp) // 2 # Dichotomy optimization bcase = parse(k-1, mid-1) # Broken eggs notbcase = parse(k,n-mid) # Unbreakable situation # fx = 1 + max(bcase, notbcase) if bcase > notbcase: rp = mid - 1 f = min(f, bcase + 1) else: lp = mid + 1 f = min(f,notbcase + 1)
Sort + two pointer search
Daily question:
Give you a n array of N integers, nums, to determine whether there are three elements a, b, c in nums, making a + b + c = 0? Please find out all the triples that meet the conditions and do not repeat.
Idea: sort the array and traverse the benchmark number from the beginning. Use two pointers to traverse at the first place of the following number. Because the array is monotonous, the search is unidirectional.
def threeSum(self,nums): nums.sort() res, k = [], 0 length = len(nums) for k in range(length-2): if nums[k] > 0: # The latter are greater than 0, and the latter are greater than zero break if(k>0 and nums[k]==nums[k-1]):#Avoid duplicate triples. Skip the next benchmark as before continue i = k + 1 j = length - 1 while i < j:#Conditions for two head and tail pointers if((nums[k] + nums[i] + nums[j] )< 0): i += 1 elif ((nums[k] + nums[i] + nums[j]) > 0): j -= 1 else: a = [nums[k], nums[i], nums[j]] res.append(a) while i<j: if(nums[i] == nums[i + 1] ):#Exclude the same tuple i+=1 elif(nums[j] == nums[j - 1]): j-=1 else: i+=1 j-=1 break return res
to flash back
Given an array candidates and a target number target, find out all combinations of candidates that can make the number and target.
Each number in candidates can only be used once in each combination.
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]: candidates.sort()#Now the array is sorted in order to ensure the monotonicity of the search direction self.res = [] if (target == 0 or len(candidates) == 0): return res def helper(tar, cur, idx): # cur records the node of the current record, so it needs to be passed down if (tar==0): # Start a new search self.res.append(cur[:]) for i in range(int(idx), len(candidates)): if (tar < candidates[i]): # The following number must be greater than tar. There is no target value. End directly break elif (i > idx and candidates[i] == candidates[i - 1]): # Avoid duplicate nodes continue # The rest is that the node is smaller than the target value, save the node and carry out the next search cur.append(candidates[i]) helper(tar - candidates[i], cur,i + 1) cur.pop() # Restore status, further search helper(target, [], 0) return self.res