NFLSOJ 6834 中国梦

NFLSOJ 6834 中国梦

题面

题目描述

崔真言 在梦里梦见自己代表祖国赴 America参加了国际信息学奥林匹克竞赛(International Olympiad in Informatics,简称 IOI czy AK IOI)并获得了金牌czy orz,颁奖会结束后崔真言想到附近的超市去买些礼物带回国送给班里的小伙伴们,崔真言心想America的巧克力是食物中的王者,给小伙伴们每人买一盒巧克力肯定会大受欢迎。于是崔真言一进超市就直奔装有巧克力的货架,一口气拿了 40 盒 巨佬牌 巧克力,然后到收银台去排队结帐, 轮到崔真言结账时,他发现自己身上只有一张大面额的Dollar了,于是他把这张钞票递了 过去,收银员迅速在收银机上算出了要找给崔真言的金额,然后打开钱柜准备找钱,崔真言看 到钱柜里的硬币按面额从大到小整整齐齐地摆放着,一种面额的硬币垒成一列,见此情景崔真言一给在座的各位出了一道题

输入格式

输入数据第一行有两个用空格隔开的整数 NN 和 KK,其中 1≤N≤3001≤N≤300,表示超市收银员 要找给小 ZZ 的金额,1≤K≤81≤K≤8,表示收银员的钱柜里共有 KK 种不同面额的硬币。

2 2 2 K + 1 K+1 K+1行每行包含一个正整数 C i C_i Ci ,其中 1 ≤ C i ≤ 100 1≤C_i≤100 1Ci100,表示一种硬币的面额,在输入数据中硬币 面额按降序排列(从最大到最小)。不同种类的硬币面额各不相同,每种硬币都取之不尽 用之不竭。

输出格式:

输出数据仅有一行包含一个整数,表示超市收银员可能的找零方案数。答案保证不会 超出长整型范围。需要注意的是如果没有面额为 1 1 1 分的硬币,有些金额将无法找零,此时 结果就输出 0 0 0

数据范围与提示

10 % 10\% 10% 的数据满足: N ≤ 50 N≤50 N50 K ≤ 3 K≤3 K3 C i ≤ 10 C_i≤10 Ci10
30 % 30\% 30% 的数据满足: N ≤ 100 N≤100 N100 K ≤ 5 K≤5 K5 C i ≤ 20 C_i≤20 Ci20
60 % 60\% 60%的数据满足: N ≤ 100 N≤100 N100 K ≤ 7 K≤7 K7 C i ≤ 50 C_i≤50 Ci50
100 % 100\% 100% 的数据满足: N ≤ 300 N≤300 N300, K ≤ 8 K≤8 K8, C i ≤ 100 C_i ≤100 Ci100

样例数据:

样例输入:

83 5
50
25
10
5
1

样例输出:

159

样例说明:

输入详解:收银员要找给小 Z 金额 83 83 83 分,共有 5 5 5 种硬币,面额分别为: 50 , 25 , 10 , 5 , 1 50,25,10, 5, 1 50,25,10,5,1
输出详解:以下是全部 159 159 159 种找零方案中的 前 15 15 15 种和最后一种:
0 × 500 × 250 × 100 × 583 × 1 0×50 0×25 0×10 0×5 83×1 0×500×250×100×583×1
0 × 500 × 250 × 101 × 578 × 1 0×50 0×25 0×10 1×5 78×1 0×500×250×101×578×1
0 × 500 × 250 × 102 × 573 × 1 0×50 0×25 0×10 2×5 73×1 0×500×250×102×573×1
0 × 500 × 250 × 103 × 568 × 1 0×50 0×25 0×10 3×568×1 0×500×250×103×568×1
0 × 500 × 250 × 104 × 563 × 1 0×50 0×25 0×10 4×5 63×1 0×500×250×104×563×1
0 × 500 × 250 × 105 × 558 × 1 0×50 0×25 0×10 5×5 58×1 0×500×250×105×558×1
0 × 500 × 250 × 106 × 553 × 1 0×50 0×25 0×10 6×5 53×1 0×500×250×106×553×1
0 × 500 × 250 × 107 × 548 × 1 0×50 0×25 0×10 7×5 48×1 0×500×250×107×548×1
0 × 500 × 250 × 108 × 543 × 1 0×50 0×25 0×10 8×5 43×1 0×500×250×108×543×1
0 × 500 × 250 × 109 × 538 × 1 0×50 0×25 0×10 9×5 38×1 0×500×250×109×538×1
0 × 500 × 250 × 1010 × 533 × 1 0×50 0×25 0×10 10×5 33×1 0×500×250×1010×533×1
0 × 500 × 250 × 1011 × 528 × 1 0×50 0×25 0×10 11×5 28×1 0×500×250×1011×528×1
0 × 500 × 250 × 1012 × 523 × 1 0×50 0×25 0×10 12×5 23×1 0×500×250×1012×523×1
0 × 500 × 250 × 1013 × 518 × 1 0×50 0×25 0×10 13×5 18×1 0×500×250×1013×518×1
0 × 500 × 250 × 1014 × 513 × 1 0×50 0×25 0×10 14×5 13×1 0×500×250×1014×513×1
……………………………………………
1 × 501 × 250 × 101 × 53 × 1 1×50 1×25 0×10 1×5 3×1 1×501×250×101×53×1

思路:

又是一道背包水题。

灰常简单啊!

要注意的是这个可以找零钱是有无限张的,所以这是个完全背包!
我们设 f   i   f_{ \ i \ } f i  表示价值为   i   { \ i \ }  i 时,最多有多少种解。
则可以轻松得到状态转移方程   { \ }   f   i   + = f   i − w [   i   ]   f_{ \ i \ } += f_{ \ i - w[ \ i \ ] \ } f i +=f iw[ i ] 
然后就没有然后了
贴上代码:

#include<bits/stdc++.h>
#define int long long
#define mem(a) memset(a,0,sizeof(a))
#define set(a,b) memset(a,b,sizeof(a))
const int MAXN = 0x3f3f3f3f;
using namespace std;
int in(){   //快读 in()
	int x=0,f=1;
	char c=getchar();
	while(!isdigit(c)){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(isdigit(c)){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}       //可以不看哦!!
int m, n;
int w[1000005];
int f[1000005];     //背包
signed main(){
	cin >> m >> n;
	for(int i = 1; i <= n; i++)
		cin >> w[i];
	f[0] = 1;
	for(int i = 1; i <= n; i++)
		for(int j = w[i]; j <= m; j++)
			f[j] += f[j - w[i]];
	cout << f[m] << endl;
	return 0;
}

H a p p y   E n d i n g ! Happy \ Ending! Happy Ending

原题:NFLSOJ 6834 中国梦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值