Problem
There are 2N people a company is planning to interview. The cost of flying the i-th person to city A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1].
Return the minimum cost to fly every person to a city such that exactly N people arrive in each city.
Example 1:
Input: [[10,20],[30,200],[400,50],[30,20]]
Output: 110
Explanation:
The first person goes to city A for a cost of 10.
The second person goes to city A for a cost of 30.
The third person goes to city B for a cost of 50.
The fourth person goes to city B for a cost of 20.
The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city.
Note:
- 1 <= costs.length <= 100
- It is guaranteed that costs.length is even.
- 1 <= costs[i][0], costs[i][1] <= 1000
解题思路
题目很简单,但是却不是那么容易求解的。此处我们可以使用动态规划的方法求解,可以看出,定义一个一维的数组来求解问题是不合适的,因为状态是由两个变量组成的,一个是当前的总人数,另一个数在这些人中有多少人去了A城市。所以很显然,我们的状态转移数组应该定义成一个二维数组。
我们定义一个二维数组 d p [ i ] [ j ] dp[i][j] dp[i][j],每一行表示前面的 i i i个人中,有 j j j个人去了A城市的花费的最小值,假设一共有m个人需要安排(m是个偶数),那么我们的数组大小就应该是 [ m + 1 , m 2 + 1 ] [m + 1, \frac{m}{2} + 1] [m+1,2m+1],这里的1表示的是多余的0。那么接下来就是看状态转移的情况。假设我们考虑第 i i i个人的情况,如果这个人要去A城市,那么,列数是需要加1的,也就是说去A城市的人数要加1,那么,有 d p [ i − 1 ] [ j − 1 ] + c o s t s [ A ] = d p [ i ] [ j ] dp[i - 1][j - 1] + costs[A] = dp[i][j] dp[i−1][j−1]+costs[A]=dp[i][j]。如果这个人要去B城市,那么列数是不变的,也就是说去A城市的人的数目是不变的,那么有 d p [ i − 1 ] [ j ] + c o s t s [ B ] = d p [ i ] [ j ] dp[i - 1][j] + costs[B] = dp[i][j] dp[i−1][j]+costs[B]=dp[i][j]。所以很明显,我们取二者之间的最小值即可,这样的两重循环,一直到返回最后的一个数据,然后返回 d p [ m ] [ m 2 ] dp[m][\frac{m}{2}] dp[m][2m]即可。
需要注意的是第0行和第0列的初始化情况。第0行一般初始化为一个很大的数,第0列则是costs中去B城市花费的累加和。
代码如下:
class Solution:
def twoCitySchedCost(self, costs):
N = len(costs)
dp = [[float('inf') for i in range(N // 2 + 1)] for j in range(N + 1)]
cnt = 0
for i in range(len(dp)):
dp[i][0] = cnt
if i < len(costs):
cnt += costs[i][1]
for i in range(1, len(dp)):
for j in range(1, min(N // 2, i) + 1):
# print(i, " ", j)
t1 = dp[i - 1][j - 1] + costs[i - 1][0]
t2 = dp[i - 1][j] + costs[i - 1][1]
dp[i][j] = min(dp[i][j], t1, t2)
return dp[-1][-1]