1. 程式人生 > >HDU2159_二維完全背包問題

HDU2159_二維完全背包問題

res sha main space sizeof 表示 ring bsp csharp

HDU2159_二維完全背包問題

輸入有:經驗,忍耐度,怪物種數,限制殺怪數 每一種怪物對應獲得的經驗值和消耗的耐久值

輸出:剩下的最大忍耐度

限制:忍耐度,殺怪個數

在這裏把忍耐度看成背包的容量,殺怪個數限制作為第二維

dp[i][j]表示在背包容量為i的時候,放了j件物品所產生的價值

接下來就是循環問題

先遍歷每一個物品(怪物) i

  然後遍歷體積(耐久值)正序遍歷——完全背包 j

    然後遍歷殺怪的個數(正序遍歷)完全背包 k

      得出dp[j][k] = max(dp[j][k],dp[j-cost[i]][k-1] + data[i]);

      在這裏要記錄一下,要保留最大的耐久值,我們就要存儲,當dp[j][k]所產生的經驗值大於等於升級所需要的經驗值時小號的最小耐久值

最後一減就ok了

#include <iostream>
#include <cstdio>
#include <string.h>
#include <cmath>
#define inf 0xffffff
using namespace std;
const int maxn = 200;
int dp[maxn][maxn];//dp[i][j]表示忍耐度為i的情況下殺j個怪獸所獲得的經驗
int data[maxn];
int cost[maxn];
int main()
{
    int e,V,n,limit;
    while(~scanf("%d%d%d%d",&e,&V,&n,&limit))
    {
        for(int i = 0;i < n;i++)
            scanf("%d %d",&data[i],&cost[i]);
        memset(dp,0,sizeof(dp));
        int res = inf;
        for(int i = 0;i < n;i++)//遍歷物品
            for(int j = cost[i];j <= V;j++)//完全背包層層遞推
                for(int k = 1;k <= limit;k++)//不管當前這只,管當前這只
                {
                    dp[j][k] = max(dp[j][k],dp[j-cost[i]][k-1] + data[i]);
                    if(dp[j][k] >= e)res = min(res,j);
                }
        if(res == inf)cout<<-1<<endl;
        else cout<<V - res<<endl;
    }
    return 0;
}

HDU2159_二維完全背包問題