P1164 小A点菜
题目入口:P1164 小A点菜
解题思路
01背包的小变动
所谓输出方案个数
我们用dp[j]
存放恰好花费j
元购买到菜品的方案数
那么对于一种菜
有两种选择 买或不买
买的话就是dp[j-wei[i]]
(已经买了j-wei[i]
元的菜品 再买上当前(i
)的菜品凑齐j
元)
不买的话就是dp[j]
(已经买了恰好j
元的菜品)
所以最终dp[j]
存放的便是上面两种选择方案的总值
此时跑一个01背包就好了 最终答案是dp[m]
到这里讲解结束
AC代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
#define mm(a) memset(a, 0, sizeof(a))
const int MAXN = 1e4+10;
int dp[MAXN], wei[MAXN];
int main() {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) scanf("%d", &wei[i]);
dp[0] = 1;
for (int i = 1; i <= n; i++)
for (int j = m; j >= wei[i]; j--)
dp[j] += dp[j-wei[i]];
printf("%d\n", dp[m]);
return 0;
}