Sicily 2502. 买珍珠 解题报告
题目传送门:2502. 买珍珠
思路: (参照 Ciel 的博客 sicily 2502 买珍珠)
1. 本题可以用动态规划的思路,开数组costs,costs[i]表示买到等级 i 的珍珠时的最少话费,所以最后costs[n - 1]就是要的结果。从低等级的珍珠开始,自底向上构建costs数组。
2. amounts数组记录少于等于每个等级的珍珠需求总数,这样做可以用amounts[i] - amounts[j]简单得到2个等级之间的珍珠总数。
3. 17~22行的for循环就是用来构建costs数组,第18行先简单假设全部珍珠用这个等级的代替,然后在19~21行逐个判断从最低一级到第 j 级不用这种珍珠代替是否能得到更少的花费。可以这样理解,每个等级的珍珠如果要用来代替低等级的珍珠的话肯定是用来代替与它相邻的低等级珍珠,而不会越过某个等级,比如不会用5级的去代替3级的,而4级的却直接去买,因为这样的话还不如用4级的代替3级的便宜(因为4级的已经买到了),这样可以证明最后costs[n - 1]就是总的最少话费。
代码:
1 #include <iostream> 2 using namespace std; 3 4 int main(){ 5 int n; 6 cin >> n; 7 int costs[n], amounts[n], prices[n]; 8 for (int i = 0; i < n; ++i) { 9 cin >> amounts[i]; 10 } 11 for (int i = 0; i < n; ++i) { 12 cin >> prices[i]; 13 } 14 for (int i = 1; i < n; ++i) { 15 amounts[i] += amounts[i - 1]; 16 } 17 for (int i = 0; i < n; ++i) { 18 costs[i] = (10 + amounts[i]) * prices[i]; 19 for (int j = 0; j < i; ++j) { 20 costs[i] = min(costs[i], prices[i] * (10 + amounts[i] - amounts[j]) + costs[j]); 21 } 22 } 23 cout << costs[n - 1] << endl; 24 return 0; 25 }