HDU1300 Pearls(可斜率优化)
question:有几种不同的珍珠。每种珍珠都有它的单价。当然质量高的珍珠价格一定也是高的。为了避免买家只买很少的珍珠。
就要求不论是买了多少个珍珠都是需要在购买数量上加10.之后乘上单价。求出总的花费!例如:买5个单价是10的珍珠。需要
的花费是(5+10)*10= 150.买100个单价是20的珍珠。需要的花费是(100+10)*20= 2200.总共需要的花费是150+2200=2350.
如果把珍珠的质量提高了。需要的105个珍珠都买单价是20的。也就是说都买质量好的。总的花费是(5+100+10)*20= 2300.
在两组数据看来。珍珠都买了高品质的了,而且花费也少了!问题是怎么样能花费最少买珍珠!
Add:合并肯定是相邻的合并。比如啊a<b<c的三种品质珍珠,如果把a珍珠和高品质的珍珠,肯定不会跳过b去和c合并,因为a和
b或者c合并都达到了减少数量10的目的,然而后者单价上去了。所以就成了相邻单元合并模型的DP。
对第i种珍珠 一:前n-1种按照前面的最优值购买(无后效性),第n种单独买 二:从第k种到第n种数量合并购买,其中k从1取到n
HDU1300
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<memory.h>
#include<algorithm>
using namespace std;
int a[1010],c[1010],dp[1010],sum[1010];
int main()
{
int T,n,i,k,tmp;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++) {
scanf("%d%d",&a[i],&c[i]);
sum[i]=sum[i-1]+a[i];
}
for(i=1;i<=n;i++){
dp[i]=dp[i-1]+(a[i]+10)*c[i];
for(k=1;k<i;k++){
tmp=dp[k-1]+(sum[i]-sum[k-1]+10)*c[i];
if(dp[i]>tmp) dp[i]=tmp;
}
}
printf("%d\n",dp[n]);
}
return 0;
}
It is your time to fight!