套路题

本文介绍了一种基于排序和01背包问题的算法,用于解决如何安排食材制作顺序以获得最大美味指数的问题。通过比较相邻食材的属性,确定优先级并进行排序。
题目大意:

一共有n件食材,每件食材有三个属性,ai,bi和ci,如果在t时刻完成第i样食材则得到ai-t*bi的美味指数,用第i件食材做饭要花去ci的时间。

众所周知,gw的厨艺不怎么样,所以他需要你设计烹调方案使得美味指数最大

做法:遇到此类题目,我们应该首先考虑x和y食材在什么情况下x比y先做要来的优

如果没有b[i]这个属性的话就是明显的01背包问题。

现在考虑相邻的两个物品x,y。假设现在已经耗费p的时间,那么分别列出先做x,y的代价:

a[x]-(p+c[x])*b[x]+a[y]-(p+c[x]+c[y])*by

a[y]-(p+c[y])*b[y]+a[x]-(p+c[y]+c[x])*bx

对这两个式子化简,得到①>②的条件是c[x]*b[y]<c[y]*b[x].

发现只要满足这个条件的物品对(x,y),x在y前的代价永远更优。

因此可以根据这个条件进行排序,之后就是简单的01背包了。


### LeetCode Top 100 题目模式与解决方法 LeetCode 的 Top 100 经典题目涵盖了多种算法和数据结构的核心概念。以下是这些题目中的常见模式以及对应的解决方案。 #### 数据结构分类 1. **数组** 数组类问是基础,通常涉及双指针、滑动窗口等技巧。 - 双指针用于处理有序数组或寻找特定条件下的两个数[^1]。 ```python def two_sum(nums, target): left, right = 0, len(nums) - 1 while left < right: current_sum = nums[left] + nums[right] if current_sum == target: return [left, right] elif current_sum < target: left += 1 else: right -= 1 return [] ``` 2. **链表** 链表操作常涉及到反转、删除节点等问。 - 使用虚拟头结点简化边界情况的处理[^2]。 ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def reverse_list(head): prev = None curr = head while curr is not None: temp = curr.next curr.next = prev prev = curr curr = temp return prev ``` 3. **栈与队列** 这些数据结构适用于括号匹配、BFS 和 DFS 等场景。 - BFS 常见于图遍历或者最短路径问[^3]。 ```python from collections import deque def bfs(graph, start_node): visited = set() queue = deque([start_node]) while queue: node = queue.popleft() if node not in visited: visited.add(node) for neighbor in graph[node]: if neighbor not in visited: queue.append(neighbor) return list(visited) ``` 4. **树** 树形结构主要考察二叉搜索树 (BST) 特性和递归实现。 - 中序遍历可以验证 BST 是否合法[^4]。 ```python def is_valid_bst(root): stack, inorder = [], float('-inf') while stack or root: while root: stack.append(root) root = root.left root = stack.pop() if root.val <= inorder: return False inorder = root.val root = root.right return True ``` 5. **动态规划** 动态规划通过子问分解来优化复杂度。 - 背包问是一个典型的例子[^5]。 ```python def knapsack(weights, values, capacity): dp = [[0]*(capacity+1) for _ in range(len(values)+1)] for i in range(1, len(values)+1): for w in range(capacity+1): if weights[i-1] <= w: dp[i][w] = max(dp[i-1][w], dp[i-1][w-weights[i-1]] + values[i-1]) else: dp[i][w] = dp[i-1][w] return dp[-1][-1] ``` 6. **回溯法** 回溯法适合组合、排列等相关问。 - N皇后问展示了如何利用剪枝减少不必要的计算[^6]。 ```python def solve_n_queens(n): result = [] cols = set(); diag1 = set(); diag2 = set() def backtrack(row, path): if row == n: result.append(path[:]) return for col in range(n): d1 = row - col; d2 = row + col if col in cols or d1 in diag1 or d2 in diag2: continue cols.add(col); diag1.add(d1); diag2.add(d2) path.append('.'*col + 'Q' + '.'*(n-col-1)) backtrack(row+1, path) cols.remove(col); diag1.remove(d1); diag2.remove(d2) path.pop() backtrack(0, []) return result ``` 7. **贪心算法** 贪心策略在某些情况下能够快速找到全局最优解。 - 区间调度是最常见的应用之一[^7]。 ```python def interval_scheduling(intervals): intervals.sort(key=lambda x: x[1]) # Sort by end time. count = 0; last_end_time = float('-inf') for start, end in intervals: if start >= last_end_time: count += 1 last_end_time = end return count ``` 8. **位运算** 位运算是高效解决问的一种方式。 - 找到只出现一次的数字可以通过异或完成[^8]。 ```python def single_number(nums): res = 0 for num in nums: res ^= num return res ``` 9. **字符串** 字符串处理经常需要用到 KMP 或者 Manacher 算法。 - 判断回文串可以用中心扩展法[^9]。 ```python def longest_palindrome(s): if not s: return "" def expand_around_center(left, right): while left >= 0 and right < len(s) and s[left]==s[right]: left -= 1; right += 1 return s[left+1:right] longest = "" for i in range(len(s)): odd = expand_around_center(i,i) even = expand_around_center(i,i+1) longer = odd if len(odd)>len(even) else even if len(longer) > len(longest): longest = longer return longest ``` #### 总结 以上列举了一些经典的 LeetCode 解决方案及其背后的理论依据。每种类型的题目都有其独特的求解思路,掌握这些通用模板有助于提高刷效率并加深理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值