本题刚开始一看求方案数,当场懵逼,现在求的背包都是最大容量,这题还能叫背包么?(我也不造)
一看小数据,二进制也不用优化(其实是不会这半背包类型)。然后判断其背包是否装满,装满就要分开初始化。这题看别人题解说是要判重,其实就是在遍历物品数量前加了个条件,如果超了背包容量就退出。还有值得注意的地方,最后遍历的才是背包数量,因为是通过遍历同一种物品数量来判断是否装满,而对于容量题目要求必须为满,所以不能为判断条件。
其实判断条件自己调个序试试就好,试试才知道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;
}