poj 1260
题意:要买若干种价值的珍珠,但买某种珍珠必须多付10颗此种珍珠的价钱,及如果买价值为1的珍珠100颗,必须付的钱数为110。一颗珍珠可以用比它贵的珍珠 充数,因此买多种珍珠的时候用贵的代替便宜的可能更省钱。例如买100颗价值为2的、1颗价值为1的,此时买101颗价值为2的为较优方案。输入要买的若 干种珍珠,可用高价珍珠充数的条件下,问最少需要花费多少钱。
经典dp:
高档次的珍珠若要和低档次的珍珠合并,那么这些低档次的珍珠必须是和它紧邻的,也就是说,它只有和第i-1,i―2,…,i-j 类珍珠合并,同时这种合并必须是连续的。用sum[i] 记录前 i 类珍珠的总数。推出状态转移方程:
dp[i] = min (dp[i], (sum[i] - sum[j] + 10) * p[i] + dp[j]);
#include<iostream> #include<fstream> using namespace std; int dp[101]; int sum[101],p[101]; int n; void read(){ // ifstream cin("in.txt"); int i,j,k; int K; cin>>K; while(K--) { cin>>n; for(i=1;i<=n;i++) { cin>>j>>p[i]; sum[i]=j+sum[i-1]; } for(i=1;i<=n;i++) { dp[i]=100000000; for(j=0;j<i;j++) dp[i]=min(dp[i],(sum[i]-sum[j]+10)*p[i]+dp[j]); } cout<<dp[n]<<endl; } } int main(){ read(); return 0; }