POJ 1260 Pearls

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 }

 

posted @ 2017-02-01 15:29  Kayden_Cheung  阅读(352)  评论(0编辑  收藏  举报
//目录