HDU2159_二維徹底揹包問題

HDU2159_二維徹底揹包問題php

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

輸出:剩下的最大忍耐度spa

限制:忍耐度,殺怪個數code

在這裏把忍耐度當作揹包的容量,殺怪個數限制做爲第二維blog

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

接下來就是循環問題string

先遍歷每個物品(怪物)  iit

  而後遍歷體積(耐久值)正序遍歷——徹底揹包   jio

    而後遍歷殺怪的個數(正序遍歷)徹底揹包   kclass

      得出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;
}
相關文章
相關標籤/搜索