Pearls POJ - 1260 dp
题意:有n种不同的珍珠 每种珍珠的价格不同 现在给出一个采购单 标注了需要不同等级的珍珠和相对于的个数(输入按价格升序排列)
其中 价格为 (当前种类价格+10)*购买数量 这样就有一种诡异的现象,当你把购买x个 低价格珍珠的时候 可能还没有把x个低价格珍珠
换成高价格珍珠来购买 总价更便宜 同时采购上的珍珠只能低的换高的价格买 让你求最小总价
思路: 1. 不能跳跃着换 比如 价格分别为 x x+1 x+2 不可能 x+1不动只换x到x+2买 因为如果x换到x+2买总价可以更便宜,那么换到x+1买肯定更更更便宜
2.因为不能跳跃着换,但存在一种情况:一层一层往右边叠 比如上述 x 换到x+1 再把原先x(现在在x+1)和x+1的换到x+2更便宜
3.购买珍珠数量一定 因为没有什么满多少打折等骚操作 所以不可能多买 多买一定要多付钱
令dp[i]表示在已知第i类珍珠时,所需支付的最低价格
则状态方程为:
dp[i]=(a[i]+10)*p[i]+dp[i-1]; //当第i种珍珠出现时,未优化价格的情况
dp[i]=min(dp[i],(sum[i]-sum[j]+10)*p[i]+dp[j]); //枚举j,价格优化
参考:https://blog.csdn.net/lyy289065406/article/details/6648131
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int maxn=3000; 6 int a[maxn],dp[maxn],sum[maxn],p[maxn]; 7 int main(){ 8 int t ; 9 scanf("%d",&t); 10 while(t--){ 11 int n; 12 sum[0]=0; 13 scanf("%d",&n); 14 for(int i=1;i<=n;i++){ 15 scanf("%d%d",&a[i],&p[i]); 16 sum[i]=sum[i-1]+a[i]; 17 } 18 dp[0]=0; 19 for(int i=1;i<=n;i++){ 20 dp[i]=(10+a[i])*p[i]+dp[i-1]; 21 for(int j=1;j<=i;j++){ 22 dp[i]=min(dp[i],dp[j-1]+(sum[i]-sum[j-1]+10)*p[i]); 23 } 24 } 25 cout<<dp[n]<<endl; 26 27 } 28 29 30 31 return 0; 32 }