0-1背包(SOJ 2222)

SOJ 2222: Health Power http://acm.scu.edu.cn/soj/problem.action?id=2222

题目意思不难理解:给出需要的能量K以及F个食物(每个食物只能用一次),每种食物i具有能量HP[i]和分数score[i]。食物应该首先满足能量要求,然后从剩下的食物中获取分数。问在满足能量需求的条件下,能获取的最大能量是多少。

解题思路:我们只需找出满足能量同时分数之和最小的食物。定义dp[j]为能量等于j时最小的分数,那么我们有

dp[j]=min{dp[j-HP[i]]+score[i],dp[j]}

由于每种食物只能用一次,所以是一个0-1背包问题。把经典的0-1背包简单地修改一下即可。注意初始化。

代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
int HP[10005];
int score[10005];
int dp[11005];
int main()
{
    int N, K, F;
    scanf("%d", &N);
    int i, j;
    int con = 100000001;
    int temp;
    int sum;
    int sum_temp;
    while (N--)
    {
        scanf("%d%d", &K, &F);
        sum = 0;
        sum_temp = 0;
        for (i = 0; i < F; i++)
        {
            scanf("%d%d", &HP[i], &score[i]);
            sum_temp += HP[i];
            sum += score[i];
        }
        if (sum_temp < K)
        {
            printf("0\n");
            continue;
        }
        dp[0] = 0;
        for (i = 1; i <= K + 10000; i++)
            dp[i] = con;
        temp = con;
        for (i = 0; i < F; i++)
            for (j = K + 10000; j >= HP[i]; j--)
            {
            dp[j] = min(dp[j - HP[i]] + score[i], dp[j]);
            if (j >= K && dp[j] < temp)
                temp = dp[j];
            }
        printf("%d\n", sum - temp);
    }
    return 0;
}
View Code

posted on 2019-03-01 13:02  小叶子曰  阅读(130)  评论(0编辑  收藏  举报

导航