http://poj.org/problem?id=1260
题意:给出几类珍珠,以及它们要买的数量和单价,珍珠的质量依次上升,价格也依次上升,计算买所有珍珠需要花的最少价格。
购买规则是这样的,不管买哪一类的珍珠,最后都需要增加10个该类珍珠,并且质量低的珍珠可以用质量高的珍珠来代替。
举个例子吧:
100 1
100 2
如果正常买的话,就是(100+10)*1+(100+10)*2=330元,如果把第一类珍珠都按照第二类珍珠来买的话,需要(200+10)*2=440元。
思路:题意的要求主要是两点:
①购买的珍珠数量必须等于各类珍珠所要求数量的总和。
②珍珠的质量只可高,不可低。
动态规划思路是这样的:
我们依次一类类的来分析,用dp[i]来表示分析到第i类珍珠时所需要花的最少价钱。
状态转移方程为dp[i]=min(dp[i] ,dp[j]+(sum[i]-sum[j]+10)*price[i] )。 //枚举j
因为质量和价格都是依次上升的,所以如果低质量的珍珠要换成高质量的珍珠,肯定优先选择高一级的珍珠来代替,因为此时珍珠的价格比后来的珍珠便宜。
所以在状态转移方程之中,sum代表珍珠总和,sum[i]代表我们分析到第i类珍珠所需要购买的珍珠总数,sum[j](0<=j<i)代表将j~i类的珍珠都用第i类珍珠来代替。
最后输出dp[n]。
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 5 const int maxn = 1000 + 5; 6 7 int n; 8 int num[maxn], price[maxn]; 9 int dp[maxn]; 10 int sum[maxn]; 11 12 int main() 13 { 14 //freopen("D:\\txt.txt", "r", stdin); 15 int t; 16 cin >> t; 17 while (t--) 18 { 19 cin >> n; 20 sum[0] = 0; 21 for (int i = 1; i <= n; i++) 22 { 23 cin >> num[i] >> price[i]; 24 sum[i] = sum[i - 1] + num[i]; 25 } 26 dp[0] = 0; 27 for (int i = 1; i <= n; i++) 28 { 29 dp[i] = (num[i] + 10)*price[i] + dp[i - 1]; //未优化之前需要花多少钱 30 for (int j = 0; j < i; j++) 31 { 32 dp[i] = min(dp[i], dp[j] + (sum[i] - sum[j] + 10)*price[i]); 33 } 34 } 35 cout << dp[n] << endl; 36 } 37 return 0; 38 }
时间: 2024-11-04 00:05:42