hdu1300 & poj1260 Pearls

题意:有n种珠宝,每件珠宝有必须要买的数量ai和单价pi,c种珠宝的单价递增。如果买了某种珠宝,需要额外付一次10*pi的费用(据说是为了防止你只买一件。。。),同时可以买同等数量单价高的珠宝代替单价低的珠宝,这样可能会省一些钱。求买完所需的珠宝需要的最少花费。

分析:

比如5……n的珠宝中,第6,7,9,11种珠宝被购买,称为A,其余是被替换的,称为B。

那么对于第4种珠宝,若选择购买B类珠宝,那么都没有选择自己优。若选择购买A类珠宝,那么选择第6种珠宝最优。原因是一样的,首先是价钱在同类中最低,而且对于1……3种珠宝的替换在同类中最有利。

可以发现,6,7,9,11 or 6,8,12,15,or 6…… 这些决策序列,对于第4种珠宝来说,都是一样的,最优决策只会在选自己和选第6种珠宝中产生。 

我提取的状态就是:dp[i][j],表示前 i 种珠宝在 i 右端第一个A类珠宝是 j 时的最优值。

状态转移:dp[i][j]=min( (a[i]+10)*p[i]+dp[i-1][i] , a[i]*p[j]+dp[i-1][j] )

第n中珠宝只能选自己,那么目标状态就是dp[n-1][n]+(a[n]+10)*p[n]

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N = 105;
 6 
 7 int dp[N][N],a[N],p[N];
 8 
 9 int solve(int s,int k)
10 {
11     if( dp[s][k]!=-1 )  return dp[s][k];
12     return dp[s][k]=min( (a[s]+10)*p[s]+solve(s-1,s),a[s]*p[k]+solve(s-1,k) );
13 }
14 
15 int main()
16 {
17     int t,n;
18 
19     scanf("%d",&t);
20     while( t-- )
21     {
22         scanf("%d",&n);
23         for(int i=1;i<=n;i++)
24             scanf("%d%d",&a[i],&p[i]);
25         memset(dp+1,-1,n*sizeof(dp[0]));
26         printf("%d\n",solve(n-1,n)+(a[n]+10)*p[n]);
27     }
28     return 0;
29 }

 

posted @ 2013-02-07 21:10  kiwi_bird  阅读(535)  评论(0编辑  收藏  举报