POJ

来源:互联网 发布:黑魂3日系女捏脸数据 编辑:程序博客网 时间:2024/06/07 03:19

题目大意:

有多组测试实例,然后告诉你要买多少种珠宝,每种珠宝各需要多少钱,以及这种珠宝要买多少个。但是有个规矩,就是,这一种珠宝不管你买多少个,只要你买了,你就得多交钱,比如你要买n个这种珠宝你就得交买n+10个这种珠宝需要的价格。然后有一个省钱的办法,就是,你可以通过买比一种珠宝高级的另一种珠宝来代替这种珠宝,这样,就可以少花10个这种珠宝的冤枉钱。问你,最省钱的办法要花多少钱。注:这里输入的每个珠宝是按照单价从小到大的顺序输入的。

分析:

假设一共有n种珠宝,如果第 i+1 种到第n种都决定好了最优的购买方式,并且第 i+1 种珠宝准备通过购买第 j 种来代替,那么对于第 i 种来说,他只有可能就是买自己或者买第 j 种,也就是说,如果 j 不等于 i+1,那么他买第 i+1 种不可能是最优的。

确定状态:

dp [ i ] [ j ] 表示在选择了第j个珠宝的前提下(j>i) 选择第 i 到第 n 个珠宝可以得到的最小值。

确定状态转移方程:

dp [ i ] [ j ] = min { dp [ i+1 ] [ j ] + a [ i ] * v [ j ] , min { dp [ i+1 ] [ k ] } + ( a [ i ] + 10 ) * v [ i ] } ;(i+1<=k<=j<=n)

描述:假如操作是从单价大的珠宝开始选取,那么在选择第i个珠宝的购买方式的时候,就是有两类选择,一类就是直接购买它自己,那购买它自己,那第i1到第n种珠宝的购买方式肯定就是dp [ i+1 ] [ k ] 里面最小的那个,即此时:dp [ i ] [ j ] = min { dp [ i+1 ] [ k ] } + ( a [ i ] + 10 ) * v [ i ];第二类选择就是选择用一个比它价值大的来代替它,那么这个比它价值大的,一定要是刚好比他价值大的,也就是:dp [ i ] [ j ] =dp [ i+1 ] [ j ] + a [ i ] * v [ j ];这里要注意 dp [ i ] [ i ] 要单独处理,因为他只能选择第一类购买方式。

下面是递推的代码:

#include<iostream>#include<math.h>#include<stdio.h>#include<string.h>#define inf 0x3f3f3f3fusing namespace std;int dp[150][150]={0};int n;int a[150]={0};int v[150]={0}; int main(){    int test;    cin>>test;    while(test--)    {        cin>>n;        for(int i=0;i<n;i++)        {            cin>>a[i];            cin>>v[i];        }        int t=0;        for(int i=n-1;i>=0;i--)        {            int lm=inf;            for(int j=i;j<=n-1;j++)            {                if(j==i)                {                    dp[i][j]=min(dp[i+1][i+1]+(a[i]+10)*v[i],t+(a[i]+10)*v[i]);                    continue;                }                dp[i][j]=min(dp[i+1][j]+a[i]*v[j],t+(a[i]+10)*v[i]);                if(lm>dp[i][j])lm=dp[i][j];            }            t=lm;        }        int min=inf;        for(int i=0;i<n;i++)        {            if(min>dp[0][i])min=dp[0][i];        }        cout<<min<<endl;        /*for(int i=0;i<n;i++)        {            for(int j=0;j<n;j++)            {                printf("%5d ",dp[i][j]);            }            cout<<endl;        }*/    }}

记小事一则:

前几天海风培训去讲了一次课,讲的就是动态规划,然后又提了一点背包问题,感觉就是自己理解的和讲出来的有很大的不一样啊。也许是自己理解的还不是很完美吧。另外准备的时候,分析一些题怎么能讲得更明白费了好多脑子,但是也有很多新的体会,不同的一些理解方法吧,或者也可以说是对解题思路不同的描述方法。这个题想的时候,一开始想用一维dp,但是描述状态一个变量怎么描述都不合适。然后想这个题和01背包有什么类似的地方,这个题如果枚举每一个物品的每一种可能的购买方式,那么有:(n!)2种购买方式,如果也是看做一种物品一种物品的确定购买方式,那么第i种物品的最优购买方式受到第i+1种物品的购买方式的影响。所以我要像01背包那样记录下来第i种珠宝的每种情况下的最优选取方式得到的最优价值,以便在确定第i-1种珠宝的每种状况下的最优选取方式时,用到选第i种的时候记录下来的所有情况中的任意一种情况。所以我想能不能用2维来描述,也就对应的时间复杂度O(n^2)。

0 0
原创粉丝点击