撿蘋果

題解:看到這個題第一反應肯定是完全揹包,但是由於袋子的容量1e8(太大,數組存不下),所以不能直接用完全揹包,用貪心的話是不正確的(如果把性價比最大的貪完,揹包容量可能還有剩餘,此時用剩餘的部分去裝蘋果,則這部分裝入的蘋果性價比可能較低,導致它的價值小於去掉一個性價比最高的加上一個性價比較高的),所以就有了分段求值,在揹包容量大於(1e3或1e4或1e5或1e6)用貪心,小於或等於(1e3或1e4或1e5或1e6)用完全揹包。

 

Description

 

以前,有個神祕的院子裏面有三種蘋果,每個蘋果的數量是無限的。有一個小姑娘帶了一個大袋子來到院子,她從來沒見過這麼多的蘋果。每種蘋果都有大小以及出售的價格,小姑娘想獲得最大的利潤,但是她不知道怎麼才能做到。於是她來向你尋求幫助,你能告訴她能獲得的最大價值嗎?

 

Input

 

第一行一個整數T(T <= 50),表示測試數據的組數。

每組測試數據有四行組成,前三行每行有兩個整數S和P,分別表示每種蘋果的大小(1 <= S <= 100)和價格(1 <= P <= 10000)

第四行有一個整數V(1 <= V <= 100,000,000)表示小姑娘袋子的大小。

 

Output

 

每組測試數據輸出組數和小姑娘能得到的最大的價值。

 

Sample Input

1
1 1
2 1
3 1
6

Sample Output

Case 1: 6

 

代碼:

#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
long long int f[1005];
struct apple{
    int w;
    int v;
    double p;
}s[4];

bool cmp(struct apple x,struct apple y)
{
    return x.p>y.p;
}

int main()
{
    int T, l = 0;
    long long int V;
    cin>>T;
    while(T--)
    {
        l++;
        memset(f,0,sizeof(f));
        for(int i = 1; i <= 3; i++)
        {
            cin>>s[i].w>>s[i].v;
            s[i].p = double(s[i].v)/double(s[i].w);
        }
        sort(s+1,s+4,cmp);
        cin>>V;
        long long int ans = 0;
        if(V > 1000)//貪心
        {
            long long int k = V - 1000;
            ans += (k / s[1].w + 1) * s[1].v;
            V = V - (k / s[1].w + 1) * s[1].w;
        }
        if(V <= 1000)//完全揹包
        {
            for(int i = 1; i <= 3; i++)
                for(int j = s[i].w; j <= V; j++)
                    f[j] = max(f[j], f[j-s[i].w] + s[i].v);
            ans += f[V];
        }
        cout<<"Case "<<l<<": "<<ans<<endl;
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章