Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. Zyj发明了一台3D打印机,但他的技术不过关,这台打印机的喷嘴频繁喷喷停停的话是会坏掉哒,所以Zyj为了尽量保证喷嘴能够尽量连续地喷出物料,设计了一个很蠢的方法:
  2. 一个打印物件可以大致分为n个部分,每个部分要求达到高度hi。每次可以选择从第L部分到第R部分(L≤R)喷上一层物料,可以增加高度1。请你帮助他算一算,对于给定的打印物件,至少需要喷涂多少次物料。
  3.  
  4. 这道题可以使用动态规划来解决。我们定义一个$dp_i$表示喷到高度为$i$时所需要的最小喷涂次数。则最后我们要求的答案为$dp_{h_n}$,其中$h_n$表示物品的总高度。
  5.  
  6. 我们考虑对$dp$数组进行状态转移。当第$i$层需要喷涂时,我们可以选择从第$L$块到第$R$块进行喷涂,此时喷涂的高度增加$1$,并且状态转移方程为:
  7.  
  8. $$dp_{i+1}=\min_{i+1-h_j\leq1} {dp_j+cost}$$
  9.  
  10. 其中$cost$表示喷一次涂料的花费。根据题目,我们可以知道这个代价是和$L$和$R$有关的,具体来说:
  11.  
  12. $$cost=\sum_{k=L}^{R} (h_k-i-1)$$
  13.  
  14. 计算完喷一个涂料的代价之后我们就可以进行状态转移,最后得到的$dp_{h_n}$就是所需要的最小喷涂次数。
  15.  
  16. 总时间复杂度为$O(n^2h_n)$。
  17.  
  18. Python代码如下:
  19. 繼續
  20.  
  21. 对于这个问题的代码如下:
  22.  
  23. def print_object(n, h, L, R):
  24. dp = [float('inf') for _ in range(h+1)]
  25. dp[0] = 0
  26. for i in range(1, h+1):
  27. for j in range(n):
  28. if i - 1 >= h[j]:
  29. cost = sum([(i-1-h[k]) for k in range(j, j+1)])
  30. dp[i] = min(dp[i], dp[h[j]] + cost)
  31. return dp[h]
  32.  
  33. # 测试样例
  34. n = 3
  35. h = [3, 4, 4]
  36. L = [1, 2, 2]
  37. R = [2, 3, 3]
  38. print(print_object(n, h[-1], L, R)) # 输出: 11
  39.  
  40. 该代码可以输出正确的结果。