博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【POJ 1260】Pearls
阅读量:6319 次
发布时间:2019-06-22

本文共 1411 字,大约阅读时间需要 4 分钟。

题意

  有n个(n≤100)等级的珍珠,等级越高单价越高,要购买一种等级的珍珠就要多付10*单价,现在需要购买一些等级的珍珠一定数量,若买更高等级的珍珠更便宜则可以买更高等级的珍珠,求最少花费。

分析

  我原来想贪心(如果该等级买,不如后一等级多买那么多更优,那就不买该等级),然而是错的,怎么证明不能贪心呢?

  网上是这么说的:如果每次贪心的将价格合并到高一级的,那么这样最终的结果并不一定正确,不具有最优子结构的特性。因为可能现在牺牲一点价格,后面的继续合并这样总的价格会更低。所以,其实这题就抽象到了多重背包的问题了。 

  反正就是要DP嘛。状态转移方程

dp[i]=min(dp[j]+(sum[i]-sum[j]+10)*p[i],dp[i]);(j=0到i-1)

dp[i]表示前i个等级最少花多少钱,sum[i]表示前i个等级共需要多少数量,j是我们截断的位置,表示j+1到i都用i等级的单价购买。

代码

#include
#include
#define N 105using namespace std;int t,n,ans,a,p[N],dp[N],sum[N];int main(){ scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1; i<=n; i++) { scanf("%d%d",&a,&p[i]); sum[i]=sum[i-1]+a; dp[i]=99999999;//也可以dp[i]=dp[i-1]+(a[i]+10)*p[i]; } for(int i=1; i<=n; i++) for(int j=0; j

还有一种写法

#include
#include
#define N 105using namespace std;int t,n,ans,a[N],p[N],dp[N],sum;int main(){ scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d%d",&a[i],&p[i]); for(int i=1; i<=n; i++) { dp[i]=99999999;//也可以dp[i]=dp[i-1]+(a[i]+10)*p[i]; sum=0; for(int j=i-1; j>=0; j--) { sum+=a[j+1]; dp[i]=min(dp[j]+(sum+10)*p[i],dp[i]); } } printf("%d\n",dp[n]); } return 0;}

转载地址:http://vbkaa.baihongyu.com/

你可能感兴趣的文章
nginx geoip 模块实现地区性负载均衡
查看>>
基于java的安全架构浅析
查看>>
我的友情链接
查看>>
yum源配置
查看>>
域控的虚拟化
查看>>
后序遍历求解判断一颗二叉树是否为平衡二叉树
查看>>
Linux的find指令
查看>>
PCB(进程控制块)--‘task_struct’
查看>>
C语言中模拟实现strcpy,strstr,strcat函数
查看>>
JavaScript_BOM对象
查看>>
01-Linux系统历史介绍
查看>>
LINUX下无killall命令解决方案
查看>>
Linux的历史命令重用及环境的配置文件
查看>>
LAMP+LNMP(六)用户认证、域名跳转与访问日志
查看>>
以太坊研究报告
查看>>
《数据库系统概念》19-并发控制
查看>>
js算出两时间个相差日期,在算出相差的具体日期
查看>>
利用java发送邮件的代码:
查看>>
Spring Boot使用Lombok来优雅编码
查看>>
阿里云安骑士免费基础版和付费企业版功能区别及作用
查看>>