poj 1260 Pearls 点击打开链接
在抱着题解磕了几道dp题后对于这题终于是有了一点思路(很水的dp大佬勿喷)。
题意:给出珍珠的价格Price和需要买的数量Count。共t组数据,每组n类珍珠。先给出的珍珠价格一定不大于后给出的珍珠,每多买一类珍珠,你要多付该类珍珠 单价*10的价格,低价格的珍珠可以由高价格的珍珠来代替。求,购买完所有的珍珠最小的价钱。
思路:dp题。
阶段:每一类珍珠为一阶段。
状态:购买从第一类到本类珍珠所需的最小价钱。
决策:对于每一类珍珠dp[i]=dp[i-1]+(Count[i]+10)*Price[i]。
然后,与之前的各项决策取min即dp[i]=min(dp[i],dp[j]+(sum[i]-sum[j]+10)*Price[i]);
其中(sum[i]-sum[j]+10)*Price[i])指的是将第j+1项的珍珠以第i项的代替所需的代价。
(有个坑点就是,珍珠的替代只能是连续的,比如说 i+2级的珍珠不能替代i级的珍珠,因为如果i+2级替代i级价格更优的话,i+1替代i也会更优。)
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Max=1e3+10;
int dp[Max];
int Price[Max],Count[Max];
int sum[Max];
int main()
{
int t,n;
scanf("%d",&t);
while(t--){
memset(dp,0,sizeof dp);
memset(sum,0,sizeof sum);
scanf("%d",&n);
for( int i=1;i<=n;i++){
scanf("%d %d",&Count[i],&Price[i]);
sum[i]=sum[i-1]+Count[i];
}
dp[0]=0;
sum[0]=0;
for(int i=1;i<=n;i++){
dp[i]=(Count[i]+10)*Price[i]+dp[i-1];
for(int j=0;j<i;j++){
dp[i]=min(dp[i],dp[j]+(sum[i]-sum[j]+10)*Price[i]);
}
}
printf("%d\n",dp[n]);
}
return 0;
}