POJ 1260 Pearls DP

POJ 1260 Pearls       DP


给出几类珍珠,以及它们的单价,要求用最少的钱就可以买到相同数量的,相同(或更高)质量的珍珠。
【规定买任一类的珍珠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元
       要求要买的珍珠的数量是一定的

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

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

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


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



 
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define exp
using namespace std;
int dp[1100];
int sum[1100],a[1100],pi[1100];
int main()
{
    int T,n;
    scanf("%d",&T);
    {
        while(T--)
        {
            scanf("%d",&n);
            sum[0]=0;
            for(int i=1; i<=n; i++)
            {
                scanf("%d%d",&a[i],&pi[i]);
                sum[i]=sum[i-1]+a[i];             <span id="transmark"></span> //
            }
            memset(dp,0,sizeof(dp));
            for(int i=1; i<=n; i++)
            {
                dp[i]=dp[i-1]+(10+a[i])*pi[i];
                for(int j=0;j<i;j++)   //注意存在 j=0 的情况
                dp[i]=min(dp[i],(sum[i]-sum[j]+10)*pi[i]+dp[j]);
            }
            printf("%d\n",dp[n]);
        }
    }
    return 0;
}


你可能感兴趣的:(POJ 1260 Pearls DP)