hdu2079 选课时间(题目已修改,注意读题)(多重背包)

本题刚开始一看求方案数,当场懵逼,现在求的背包都是最大容量,这题还能叫背包么?(我也不造)


一看小数据,二进制也不用优化(其实是不会这半背包类型)。然后判断其背包是否装满,装满就要分开初始化。这题看别人题解说是要判重,其实就是在遍历物品数量前加了个条件,如果超了背包容量就退出。还有值得注意的地方,最后遍历的才是背包数量,因为是通过遍历同一种物品数量来判断是否装满,而对于容量题目要求必须为满,所以不能为判断条件。


其实判断条件自己调个序试试就好,试试才知道hdu2191遍历对象为价值(求最大价值),所以最后一层循环为价值。总而言之,要求的遍历对象为什么,最后一层for就遍历什么。

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <cmath>

using namespace std;

const int N = 55;

int sum;
int dp[N];

struct node
{
    int a, b;
}cla[N];

int main()
{
  //  freopen("in.txt", "r", stdin);
    int t, n, k;
    scanf("%d", &t);
    while(t --)
    {
        memset(dp, 0, sizeof(dp));
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= k; i ++)
        {
            scanf("%d%d", &cla[i].a, &cla[i].b);
        }
        dp[0] = 1;
        for(int i = 1; i <= k; i ++)
            for(int j = n; j >= cla[i].a; j --)//容量
                for(int l = 1; l <= cla[i].b; l ++)//数量
                {
                    if(j - cla[i].a * l >= 0) dp[j] += dp[j - cla[i].a * l];
                    else break;
                }
        printf("%d\n", dp[n]);
    }
    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值