DP POJ1260

题目

题目链接

1.题意:

 给出几类珍珠,以及它们的单价,要求用最少的钱就可以买到相同数量的,相同(或更高)质量的珍珠。
对于样例Input的第一个例子:
2
100 1
100 2
按常规支付为 (100+10)*1 + (100+10)*2 =330元
但是全部按第二类珍珠的价格支付,同样买200个,虽然总体质量提升了,但是价格也提高了: (202+10)*2=424元。

2.要求:

  • N, case数
  • c<100, 珍珠的种类
  • i 行:a[i]是要求买该中珍珠的个数。
         p[i] 是该珍珠的价格。
  • 样例是按照珍珠的价格升序排列。

思路:

  这个题目和图像压缩是一模一样的。因为每次购买一种新珍珠的时候都要支付额外的金额,因此该题的主要任务是找出一个分段,确定从哪几种珍珠处断开,使得花费最小。

  • dp[i] :购买前 i 种珍珠所需要的最小花费
  • sum[i] : 前 i 中珍珠总计珍珠数目
  • dp[i]=min(dp[i],dp[k]+(sum[i]sum[k]+10)p[i]) k0 ~ i1 .

代码:

#include <cstdio>
#include <iostream>
#include <cmath>

using namespace std;

int p[100+5],dp[100+5],a[100+5],sum[100+5];

int main()
{
    int cas;
    scanf("%d",&cas);
    while(cas--)
    {
        int N;
        scanf("%d",&N);
        memset(sum,0,sizeof(sum));
        for(int i = 1; i<=N; i++){
             scanf("%d%d",&a[i],&p[i]);
             sum[i] = sum[i-1] + a[i];
        }
        dp[0] = 0;
        for(int i = 1; i<=N; i++){
            dp[i] = 100000000;
            for(int k = 0; k<i; k++)
                dp[i] = min(dp[i], dp[k]+(sum[i]-sum[k]+10)*p[i]);
        }
        printf("%d\n",dp[N]);
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值