本文主要是介绍【P1164 小A点菜】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
小A点菜
题目背景
uim 神犇拿到了 uoi 的 ra(镭牌)后,立刻拉着基友小 A 到了一家……餐馆,很低端的那种。
uim 指着墙上的价目表(太低级了没有菜单),说:“随便点”。
题目描述
不过 uim 由于买了一些书,口袋里只剩 M M M 元 ( M ≤ 10000 ) (M \le 10000) (M≤10000)。
餐馆虽低端,但是菜品种类不少,有 N N N 种 ( N ≤ 100 ) (N \le 100) (N≤100),第 i i i 种卖 a i a_i ai 元 ( a i ≤ 1000 ) (a_i \le 1000) (ai≤1000)。由于是很低端的餐馆,所以每种菜只有一份。
小 A 奉行“不把钱吃光不罢休”,所以他点单一定刚好把 uim 身上所有钱花完。他想知道有多少种点菜方法。
由于小 A 肚子太饿,所以最多只能等待 1 1 1 秒。
输入格式
第一行是两个数字,表示 N N N 和 M M M。
第二行起 N N N 个正数 a i a_i ai(可以有相同的数字,每个数字均在 1000 1000 1000 以内)。
输出格式
一个正整数,表示点菜方案数,保证答案的范围在 int 之内。
样例 #1
样例输入 #1
4 4
1 1 2 2
样例输出 #1
3
提示
2020.8.29,增添一组 hack 数据 by @yummy
#include <iostream>
using namespace std;
#define N 101int n,m,a[N],f[N][10001];//f数组保存方法总数量int main() {cin >>n>>m;//n代表菜的数量,m代表当前有多少钱for (int i = 1; i <= n; i++) cin >>a[i];//输入每种菜的价格//当前第i种物品恰好为j元钱,所以可以只买它自己。//这种情况其实包含在1中,但是由于f[i][0]=0,所以不会算入这种情况。//所以我们要把所有的f[i][0]更新成1,这样就可以计算上面所述的那种情况//i代表哪个菜,0可以理解为你的钱和当前菜品的价格一样,两者做了减法,如同j - a[i]for (int i = 0; i <= n; i++) f[i][0] = 1; // 初始化第一列,全部为1for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++) {//不买当前第i道菜品,这时候,也就是前i-1个物品凑成j的方案,即f[i][j]+=f[i-1][j]f[i][j] += f[i - 1][j];//买当前第i道菜品,这个时候前i-1个物品所需要的钱应该是j-a[i],//也就是说前i个物品中所有能凑出j-a[i]元的方案再加上当前这道菜品,//就可以变成前i个物品所需的钱为j的方案数。//即f[i][j]+=f[i-1][j-a[i]]if (j >= a[i]) f[i][j] += f[i - 1][j - a[i]]; cout << f[i][j] << " ";//输出当前i个物品凑成j元的方案数}cout << endl;}cout << f[n][m] << endl;return 0; // 程序执行成功,返回0
}
这个题目,我在做的时候,我发现这个题目重在策划,策划一个问题的解决思路,纯纯的逻辑思维,反而有点加大难度。
这篇关于【P1164 小A点菜】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!