HDU 2018 undefined

题目思路:完全背包,dp[i][j]代表,砍j只怪,用i点疲劳最多能获得的经验值.

和平常的完全背包不一样的是多了一个限制条件:最多只砍S只怪,所以我们应该多一重循环来q:for 1->S,代表某种怪砍q只。

代码:

#include<cstdio>
#include<stdio.h>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
#define MAX 1005

using namespace std;

int dp[MAX][MAX],w[MAX],v[MAX];

int main()
{
    int n,m,k,s,i,j,q,minn;

    while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
    {
        minn=INF;
        memset(dp,0,sizeof(dp));
        for(i=1;i<=k;i++)
        {
            scanf("%d%d",&v[i],&w[i]);
        }
        for(i=1;i<=m;i++)
        {
            for(j=1;j<=k;j++)
            {
                for(q=1;q<=s;q++)
                {
                    int cnt=1;
                    while(cnt*w[j]<=i && cnt<=q)
                    {
                        dp[i][q]=max(dp[i][q],dp[i-cnt*w[j]][q-cnt]+cnt*v[j]);
                        cnt++;
                    }
                }
            }
            if(dp[i][s]>=n)//如果获得的经验已经大于n就没必要进行下去了
                break;
        }
        if(i<=m)
            printf("%d
",m-i);
        else
            printf("-1
");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/alan-W/p/5758299.html