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 ",dp[n]); } return 0; }