题目解析
如果我们直接忽略数据范围,不难发现可以使用完全背包的DP模型来解决这道问题,定义 dp[i][j]dp[i][j]dp[i][j] 为前 iii 个礼物,使用 jjj 个糖果能够获得的最多金币。
但是注意到本题的数据范围 N,M (1≤N,M≤105)N, M\ (1 \le N, M \le 10^5)N,M (1≤N,M≤105) 如果使用上述递推式,时间复杂度为 O(N×M)\mathrm{O}(N \times M)O(N×M)。会超出本题的时间限制。
那么进一步分析题目我们会发现对于每个礼物 AiA_iAi ,制作出礼物需要的糖果为 f(Ai)f(A_i)f(Ai ),其中 1≤Ai≤1091 \le A_i \le 10^91≤Ai ≤109,我们不难发现,2≤f(Ai)≤632 \le f(A_i) \le 632≤f(Ai )≤63;而对于每个 f(Ai)f(A_i)f(Ai ) 由于可以重复制作同一种礼物,所以只需要取 maxBi\max{B_i}maxBi 即可。
所以我们可以转换 dp[i][j]dp[i][j]dp[i][j] 定义为制作需要糖果数量不超过 iii 的礼物,使用 jjj 个糖果能够获得的最多金币。
那么此时的时间复杂度转化为 O(K×M)\mathrm{O}(K \times M)O(K×M) 其中 K=63K = 63K=63。
AC代码
C++ AC代码:
Python AC代码:
复杂度分析
将所有的物品进行转化时间复杂度为 O(NW)\mathrm{O}(NW)O(NW), 其中 W=10W = 10W=10;
动态规划的时间复杂度为 O(KM)\mathrm{O}(KM)O(KM),其中 K=63K = 63K=63。
总的时间复杂度为 O(NW+MK)\mathrm{O}(NW + MK)O(NW+MK)。