首页 > 代码库 > poj 1260 Pearls ( 区间dp )
poj 1260 Pearls ( 区间dp )
链接:poj 1260
题意:给出n类珍珠,所需它们的数量,以及它们的单价,
要求用最少的钱就可以买到相同数量的,相同(或更高)质量的珍珠。
注:价格更高的珍珠等级更高,支付规则为:
买任一类的珍珠n个(单价:p),都要支付(n+10)*p的钱
例如:
3
1 10
1 11
100 12
需要买第一类1个,第二类1个,第三类100个
按常规支付为 (1+10)*10 + (1+10)*11 + (100+10)*12 = 1551元
但是如果全部都按照第三类珍珠的价格支付,同样是买102个,
而且其中总体质量还被提高了,但是价格却为:(102+10)*12 = 1344元下降了
分析:珍珠的替代必须是连续的,不能跳跃替代,
因为如果用第i+2类去替代第i类珍珠,会使最终的支付价格降低,
那么用第i+1类去替代第i类珍珠会使最终的支付价格更加低
在珍珠类型的总区间[1,n]中划分多个子区间,
在闭区间in-jn的珍珠全部按第jn类珍珠的价格pn支付。
这些区间互不相交。其余珍珠按其原价支付。
要求找出最优的划分方案,使得最终支付价格最低。
令dp[i]表示在已知第i类珍珠时,所需支付的最低价格
则状态方程为:
dp[i]=(a[i]+10)*p[i]+dp[i-1]; //当第i种珍珠出现时,按常规支付第i类的价格
dp[i]=min(dp[i],(s[i]-s[j]+10)*p[i]+dp[j]); //枚举j,价格优化
s[i]为需要第1类珍珠到第i类珍珠的总个数
#include<stdio.h> #define min(a,b) a<b?a:b int main() { int T,n,i,j,a[105],p[105],s[105],dp[105]; scanf("%d",&T); while(T--){ scanf("%d",&n); s[0]=0; for(i=1;i<=n;i++){ scanf("%d%d",&a[i],&p[i]); s[i]=s[i-1]+a[i]; } dp[0]=0; for(i=1;i<=n;i++){ dp[i]=dp[i-1]+(a[i]+10)*p[i]; for(j=0;j<i;j++) dp[i]=min(dp[i],dp[j]+(s[i]-s[j]+10)*p[i]); } printf("%d\n",dp[n]); } return 0; }
poj 1260 Pearls ( 区间dp )
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。