• POJ-1260 Pearls---DP


    题目链接:

    https://cn.vjudge.net/problem/POJ-1260

    题目大意:

    给定一系列的不同质量项链上的珠宝数量和价格(按质量升序给出,同时价格也升序)。可以用价格高的珠宝来替代价格低的珠宝。这样或许可以节省总钱数。而题目就是要求出购买所有数量的珠宝所需支付的最低价格。

    解题思路:

    例如样例Input的第二个例子:

    3

    1 10

    1 11

    100 12

    需要买第一类1个,第二类1个,第三类100个

    按常规支付为 (1+10)*10 + (1+10)*11 + (100+10)*12 = 1551元(一共买了102个珍珠)

    但是如果全部都按照第三类珍珠的价格支付,同样是买102个,而且其中总体质量还被提高了,但是价格却下降了:(102+10)*12 = 1344元

    本题关键点在于:

    (1)       要求要买的珍珠的数量是一定的

    (2)       所买的珍珠的质量允许提高,但不允许下降(即可以用高质量珍珠替代低质量)

    (3)       输入时,后输入的珍珠价格一定比前面输入的要贵

    (4)       由(2)(3)知,珍珠的替代必须是连续的,不能跳跃替代(这个不难证明,因为假如用第i+2类去替代第i类珍珠,会使最终的支付价格降低,那么用第i+1类去替代第i类珍珠会使最终的支付价格更加低)

    根据这4个约束条件,那么购买珍珠的方案为:

    在珍珠类型的总区间[1,c]中划分多个子区间,其中在闭区间i1~j1的珍珠全部按第j1类珍珠的价格p1支付,在闭区间i2~j2的珍珠全部按第j2类珍珠的价格p2支付,…在闭区间in~jn的珍珠全部按第jn类珍珠的价格pn支付。 这些区间互不相交。

    其余珍珠按其原价支付。

    要求找出最优的划分方案,使得最终支付价格最低。

    令dp[i]表示在已知第i类珍珠时,所需支付的最低价格

    则状态方程为:

    dp[i]=(a[i]+10)*p[i]+dp[i-1];  //当第i种珍珠出现时,未优化价格的情况

    dp[i]=min(dp[i],(sum[i]-sum[j]+10)*p[i]+dp[j]);  //枚举j,价格优化

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #include<stack>
     8 #include<map>
     9 #include<sstream>
    10 #define Mem(a, b) memset(a, b, sizeof(a))
    11 using namespace std;
    12 typedef long long ll;
    13 int dp[1005], sum[1005];//dp[i]表示前i个的最低价格,sum[i]表示前i个的数目
    14 int a[1005], p[1005];//输入的数据,分别是个数和价格
    15 int main()
    16 {
    17     int T, n;
    18     cin >> T;
    19     while(T--)
    20     {
    21         Mem(a, 0);
    22         Mem(p, 0);
    23         Mem(dp, 0);
    24         Mem(sum, 0);
    25         cin >> n;
    26         for(int i = 1; i <= n; i++)cin >> a[i] >> p[i], sum[i] = sum[i - 1] + a[i];
    27         for(int i = 1; i <= n; i++)
    28         {
    29             dp[i] = dp[i - 1] + p[i] * (a[i] + 10);
    30             for(int j = 0; j < i; j++)
    31                 dp[i] = min(dp[i], dp[j] + (sum[i] - sum[j] + 10) * p[i]);//只能有高价格代替低价格
    32         }
    33         cout<<dp[n]<<endl;
    34     }
    35     return 0;
    36 }
  • 相关阅读:
    javascript 注意事项汇总
    Object.prototype.toString方法
    PHPStorm使用心得
    JavaScript基于原型链的继承
    PHP重定向的3种方式
    Android应用与开发环境
    PHP时间处理
    cocos2dxna 游戏中如何控制后退键实现目的性跳转
    wp7 独立存储空间在真机和虚拟机测试的时候数据不一样
    c#获取交叉数组的行、列数
  • 原文地址:https://www.cnblogs.com/fzl194/p/9010700.html
Copyright © 2020-2023  润新知