1. 程式人生 > >C. Party Lemonade(DP,貪心,數位)

C. Party Lemonade(DP,貪心,數位)

題目大意:有n種不同規格的飲料,容量分別為L,並給出每種飲料的價格。

現在題目要求至少購買 l升的飲料,最少需要多少錢。

思路:

首先需要對價格進行一個預處理,如果val[i]*2<val[i+1],那麼是沒有意義的去購買第i+1種飲料,因為顯然購買兩瓶第i種的飲料更加的實惠,所以我可以用兩瓶第i種飲料的價格和來代替第i+1種飲料的價格。

因此,在進行預處理之後,他的價效比呈現不遞減的趨勢,即後一種飲料的價效比大於等於前一種飲料的價效比。

所以我們購買飲料時,從後往前購買。

購買策略,這裡主要用到DP的思想,首先如果飲料的容量小於等於需求的容量,那麼先購買幾瓶,直道需求的量小於當前種類的飲料容量,為什麼這麼做?因為之前已經說過越是後面的價效比越高,儘可能的多買。

此時當需求容量小於當前種類飲料容量的時候,就會有兩種可能,要麼在購買一瓶當前種類的飲料,要麼購買比當前種類容量更小的那幾種飲料。

#include <bits/stdc++.h>
using namespace std;
#define maxn 200
int n,l;
int val[maxn];
int main()
{


    while(~scanf("%d%d",&n,&l))
    {
        for(int i=1;i<=n;i++)scanf("%d",&val[i]);
        for(int i=2;i<=n;i++)
        {
            val[i]=min(val[i],val[i-1]*2);
        }
        long long ans=(long long )4e18;
        long long sum=0;
        for(int i=n;i>=1;i--)
        {
            int v=1<<(i-1);
            int need=l/v;
            sum+=(long long )need*val[i];
            l%=v;
            ans=min(ans,sum+(l>0)*val[i]);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}