FATE (HDU 2159) (full backpack)

Topic links: http://acm.hdu.edu.cn/showproblem.php?pid=2159
subject to the effect:
N-> required experience
m-> the greatest degree of patience
k-> number of types of monster
s-> most Shaguai number
each monster has two properties: a-> experience obtained; b-> to lose endurance
monster there are numerous

Solution:
We can limit the value of patience, seeking the most experience points available in each state (tolerance value in the range).
Because we are the largest remaining patience required value, so we can then traverse dp, look at the experience meets the upgrade, and then see if the number of monsters meet in s, if are met, directly answer, if traversed again not meet the conditions of the answer, output -1.
there is a place to handle the number of monsters num [], when we update dp, dp updated, num will update the num [j-monster [i He killed a blame] .b] basis.

Code:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <list>
#include <map>
#define P(x) x>0?x:0
#define INF 0x3f3f3f3f

using namespace std;
typedef long long ll;
typedef vector<int>:: iterator VITer;
const int maxN=105;

int n,m,k,s;
int dp[maxN],num[maxN];
int ans,ansi;
struct node
{
    int a,b;
}monster[maxN];

void init()
{
    memset(dp,0, sizeof(dp));
    memset(num,0, sizeof(num));
    ans=0;
}

int main()
{
    while(~scanf("%d%d%d%d",&n,&m,&k,&s))
    {
        init();
        for(int i=1;i<=k;i++)
        {
            scanf("%d%d",&monster[i].a,&monster[i].b);
        }
        for(int i=1;i<=k;i++)//怪兽的种类数
        {
            for(int j=monster[i].b;j<=m;j++)//忍耐值为限
            {
                if(dp[j]<=dp[j-monster[i].b]+monster[i].a)//最大的经验值
                {
                    dp[j]=dp[j-monster[i].b]+monster[i].a;
                    num[j]=num[j-monster[i].b]+1;
                }
            }
        }
        int i=1;
        for(;i<=m;i++)
        {
            if(dp[i]>=n)//经验值够了
            {
                ans=dp[i];
                ansi=i;
                if(num[ansi]<=s)//杀怪数在范围内
                {
                    printf("%d\n",m-ansi);
                    break;
                }
                else//杀怪数不在范围内,继续搜
                    continue;
            }
        }
        if(i==(m+1))//不能得到所需经验值或者需要杀的怪大于最多的杀怪数
            printf("-1\n");
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_44049850/article/details/94720790