• POJ1260Pearls


    转载请注明出处:優YoU  http://user.qzone.qq.com/289065406/blog/1300164274

    大致题意:

    给出几类珍珠,以及它们的单价,要求用最少的钱就可以买到相同数量的,相同(或更高)质量的珍珠。

    【规定买任一类的珍珠n(价格为p),都要支付(n+10)*p的钱,即额外支付10*p

     

    例如样例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

     

    而对于样例Input的第一个例子:

    2

    100 1

    100 2

    按常规支付为 100+10*1 + (100+10)*2 =330

    但是全部按第二类珍珠的价格支付,同样买200个,虽然总体质量提升了,但是价格也提高了: (202+10)*2=424

     

    本题关键点在于:

    (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,价格优化

     

    dp[0]=0;  //Dp初始化

     1 //Memory Time 
    2 //220K 0MS
    3
    4 #include<iostream>
    5 using namespace std;
    6
    7 int min(int a,int b)
    8 {
    9 return a<b?a:b;
    10 }
    11
    12 int main(int i,int j)
    13 {
    14 int test;
    15 cin>>test;
    16 while(test--)
    17 {
    18 /*Input & Initial*/
    19
    20 int c;
    21 cin>>c;
    22
    23 int* a=new int[c+1]; //某类珍珠数目
    24 int* p=new int[c+1]; //某类珍珠单价
    25 int* dp=new int[c+1]; //dp[i]表示在已知第i类珍珠时,所需支付的最低价格
    26 int* sum=new int[c+1];//sum[i]=∑a[i]
    27
    28 sum[0]=0;
    29 for(i=1;i<=c;i++)
    30 {
    31 cin>>a[i]>>p[i];
    32 sum[i]=sum[i-1]+a[i];
    33 }
    34
    35 /*Dp*/
    36
    37 dp[0]=0; //Dp初始化
    38 for(i=1;i<=c;i++)
    39 {
    40 dp[i]=(a[i]+10)*p[i]+dp[i-1]; //当第i种珍珠出现时,未优化价格的情况
    41 for(j=0;j<i;j++) //枚举第i种珍珠前的每一种珍珠,寻找最优价格
    42 dp[i]=min(dp[i],dp[j]+(sum[i]-sum[j]+10)*p[i]); //在求dp[i]前,对于每一个j<i,dp[j]的最优值已求出
    43 } //(sum[i]-sum[j]+10)*p[i]即第j+1~i种珍珠被第i种珍珠替代后的价格
    44 cout<<dp[c]<<endl;
    45
    46 delete a,p,dp,sum;
    47 }
    48 return 0;
    49 }
  • 相关阅读:
    SQL2012远程连接到SQL2008时的问题:已成功与服务器建立连接,但在登陆过程中发生错误。
    常用正则表达式
    ASP.NET不拖控件教程(1)-认识JSON
    ASP.NET服务器控件对应的HTML标签
    Apache Ranger 1.1.0源码导入IDEA并运行调试security-admin web模块
    【JDK源码分析】线程池ThreadPoolExecutor原理解析
    【JDK源码分析】同步工具Exchanger,它的内部实现原理你看懂了吗?
    【JDK源码分析】并发包同步工具Semaphore
    【JDK源码分析】并发包同步工具CountDownLatch
    【JDK源码分析】并发包同步工具CyclicBarrier
  • 原文地址:https://www.cnblogs.com/lyy289065406/p/2122652.html
Copyright © 2020-2023  润新知