题意:给出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;
}