1. 程式人生 > >hdu2079 選課時間(題目已修改,注意讀題)(多重揹包)

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;
}