BUPT final B题: add number

B.Add number

Time Limit: 1000MS Memory Limit: 65536K

Description Employees of Baidu like to play a game called Making Numbers. It goes like this: there are two players in the game, one is called little A, the other little B. There are some cards with a number on each one of them, little A chooses a number X from 1 to N randomly, while little B has to choose some cards, the sum of which equals X. Now there are already M cards with numbers, and K blank cards. At the beginning of the game, little B is allowed to write numbers on the blank cards. Now little B wants to know, if it is possible to write some numbers that will assure him of the victory, that is to say, if it is possible for him to make up any number from 1 to N with the cards.

Input

The input consists of several test cases. The first line is an integer T , in the second line of each case are 3 numbers, N M K, the second line shows the number that is already written on M cards. 0<N<100000000,0<=M<20,0<K<20

The numbers in the second line are above 0, smaller than or equals N, in non-descending order. Input ends with 0 0 0, which doesn't need to be processed.

Output

If little B can make it, output "YES", else output "NO".

Sample Input

3

15 0 4

12 3 2

3 3 3

13 3 2

3 3 3

Sample Output

YES

YES

NO

 

解题报告:

 

题目大意:

两个人玩游戏,一个人从1-》n中任意的说出一个数字,另一个人要从一堆标着数字的卡片中找出一些卡片

,使得卡片上的数字之和为第一个人说出的数字,现在这堆卡片中有M张卡片是已经标上数据,还有K张是没有标上数据。

题目问:第二个人能否通过自己对K张卡片标上数字,使得不论第一个人说什么数字,都能够从卡片中找出所对应的和

题目要求:通过标记K张卡片,使得M+K张卡片上的数据通过不同的组合可以组合出1-》n中的所有的值 

 

解题报告:

思路是这样的,

现在已经有了M个数字,而且这M个数字是升序排列的(这个很关键,是贪心算法的基础,也是计算出最少cnt的基础),

通过往其中加入新数字,使得可以表示1-》N所有数字, 

问题是怎么往里面加入数据,使得加入数据的个数最少,

而且通过计算出最少加入的数字数cnt,与K比较,

如果cnt<=K小,那么没问题,可行。

否则,不可行。 

 

假设现在我们现有的数据(这些个数据包括题目给的数据+我们后来加入的数据)已经

能够拼凑出1->x范围内(包括1和x)的所有的数据,但是这时候x 比N还是要小,

那么接下来,我们只需要再加入一个值为x+1的卡片即可得到1->2x+1范围的所有的值,

就以这个思想继续加,知道最后x的值要比N大。

同时也要用上已有的数字,假设现在我们现有的数据已经能偶凑出1-》x范围内的所有数据,这时有一个题目给的数据array[i]比x要小,

那么这时x加上这个数字,那么就可以表示1->x + array[i]范围的数据了。 

通过充分利用其题目已有的数据,来扩大x所能够表示的范围,从而减少加入的数据的个数。

 

 

一下面case为例:

N= 200   M= 4      K = 8

已有的卡片数据是5 20 100 500

刚开始x = 0, cnt = 0 

由于已有数组中没有1,所以需要加入一个1数字,加入卡片1 

x = 1, cnt = 1,  这时候1-》1范围的数字可得,1 <100,所以加入卡片2

x = 1 +2= 3, cnt = 2, 这个时候1-》3范围上的数字可得, 3 《200 ,同时比5要小,于是加入卡片4

x= 3+ 4 = 7, cnt = 3, 这个时候1-》7范围上的数字可得, 7 《200,同时比5要大,那么加上5(卡片原有数字),说明可以表示1->12范围上数字

x = 7+ 5 = 12, cnt = 3, 这个时候1->12范围上的数字可得, 12 《 200,同时比20小,那么加上卡片13,

x = 12+ 13 = 25, cnt = 4, 这个时候1-》25范围上的数字可得,25 < 200,同时比20大,那么加上20(卡片原有数字)

x = 25 +20 = 45, cnt = 4, 这个时候1-》45范围上的数字可得, 45 《 200,同时比100小,那么加上卡片46,

x = 45 + 46 = 91, cnt = 5 ,这个时候1-》91范围上的数字可得, 91 《200, 同时比100小,那么加上卡片92,

x = 91 +92 = 183, cnt = 6, 这个时候1-》 183范围上的数字可得, 183 《 200,同时比100大,那么加上100(原有卡片数字),

x = 183 + 100 = 283, cnt = 6, 这个时候1->283范围上的数字可得,283 》 200,OK了

 

也就是说通过加入1, 2, 4, 13, 46, 92 这6张卡片就能够使得1-》283范围上的任意可表示。

加上原有的 5 20 100 500卡片。

1, 2, 4, 5, 13, 20, 46, 92, 100, 500.

前面1个数可以表示1-》1的范围。

前面2个树可以表示1-》3的范围。

前面3个数可以表示1-》7的范围。

前面4个数可以表示1-》12的范围。

前面5个数可以表示1-》25的范围。

前面6个数可以表示1-》45的范围。

前面7个数可以表示1-》91的范围。

前面8个数可以表示1-》183的范围。

前面9个数可以表示1-》283的范围。

 

由于最后cnt = 6 < 8 ,所以最后可行 

 

 

下面是官方的代码:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值