TaoTao要喫雞(01揹包)

鏈接:https://www.nowcoder.com/acm/contest/74/B
來源:牛客網

題目描述

Taotao的電腦帶不動絕地求生,所以taotao只能去玩pc版的荒野行動了,
和絕地求生一樣,遊戲人物本身可以攜帶一定重量m的物品,裝備揹包
之後可以多攜帶h(h爲0代表沒有裝備揹包)重量的東西。玩了幾天
taotao發現了一個BUG,當裝備揹包之後,如果可攜帶重量沒有滿,就
可以拿一個任意重的東西。(解釋看樣例)有一天taotao空降到了一個
奇怪的島上,島上有n件裝備,每個裝備都有重量Wi和威力值Vi,但taotao
不認識這些裝備,所以他來求助你,挑選威力最大的裝備,幫助他喫雞。
輸入描述:
本題有多組輸入(小於10),當n=0時結束輸入。
第一行輸入n,m,h。n,m,h爲整數,並且0<=n,m,h<=100,
接下來n行,每行輸入第i個物品的物品的重量Wi和威力值Vi。0<=Wi,Vi<=100.
輸出描述:
輸出最大威力值,每組輸出一行。
示例1
輸入
3 3 3
2 3
3 2
2 3
0
輸出
8
說明
可攜帶的總重量爲6,當拿了前兩件裝備,此時容量爲5/6,還可以再拿第三件物品。

做這套題的時候就已經開始快兩個小時了。。。總是忘記時間。
一開始的想法是把每次背的重量標記下來,如果背滿輸出,背不滿遍歷一下未標記的重量,找最大價值。但是因爲最後還剩十分鐘纔開始寫的這道題,有點細節沒來得及考慮,於是匆匆忙忙交了一個不完整的代碼果斷WA了。
(2rd 補充說明,這個方法有bug,具體看評論回覆。棄用)

另一種方法就是暴力,因爲數據小,所以讓總揹包重量爲m+h-1,減去一個1代表肯定背不滿。那樣就可以遍歷每一個揹包,在遍歷當前揹包時,此包不背,去背其它包。
這樣ans=max(ans,最後得到的最大價值+當前揹包的價值)。

題目有句話說:當裝備揹包之後,如果可攜帶重量沒有滿,就
可以拿一個任意重的東西,所以要考慮h爲0的時候,即使背不滿也不能去拿其它的物品。

 

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#include<algorithm>
#define max(a,b)   (a>b?a:b)
#define min(a,b)   (a<b?a:b)
#define swap(a,b)  (a=a+b,b=a-b,a=a-b)
#define X (sqrt(5)+1)/2.0  //Wythoff
using namespace std;
typedef long long int LL;
const int MAXL(2*1e2);
const int INF(0x3f3f3f3f);
const int mod(1e9+7);
int dir[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};
int weight[MAXL+50];
int value[MAXL+50];
int dp[MAXL+50];
int main()
{
    ios_base::sync_with_stdio(false);
    int n,m,h;
    while(cin>>n&&n)
    {
        cin>>m>>h;
        memset(dp,0,sizeof(dp));
        for(int i=1; i<=n; i++)
            cin>>weight[i]>>value[i];
        if(!h)
        {
            for(int i=1; i<=n; i++)
            {
                for(int j=m; j>=weight[i]; j--)
                {
                    dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);
                }
            }
            cout<<dp[m]<<endl;
        }
        else
        {
            int w=m+h-1;
            int ans=0;
            for(int k=1; k<=n; k++)
            {
                memset(dp,0,sizeof(dp));
                for(int i=1; i<=n; i++)
                {
                    if(i==k) continue;
                    for(int j=w; j>=weight[i]; j--)
                    {
                        dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);
                    }
                }
                ans=max(ans,dp[w]+value[k]);
            }
            cout<<ans<<endl;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章