轉載請註明:@小五義 http://www.cnblogs.com/xiaowuyi
題目:借書方案
內容:小明有五本新書,要借給A、B、C三位小朋友,若每人每次只能借一本,則可以有多少種不同的借法。
問題分析和演算法設計:
本問題實際上就是一個排列問題,即求從5個中取3個進行排列的方法有多少。首先對五本書從1至5進行編號,然後使用窮舉的方法,假設三個人分別借這五本書中的一本,當三個人所借的書的編號都不相同時,就滿足題意。
具體代碼:
# -*- coding: cp936 -*-##@小五義 http://www.cnblogs.com/xiaowuyi'''借書方案:小明有五本新書,要借給A、B、C三位小朋友,若每人每次只能借一本,則可以有多少種不同的借法。'''count=0 #記錄第幾種分法print "假設五本書分別為1,2,3,4,5,主要借法有"for a in range(1,6): for b in range(1,6): if a!=b: for c in range(1,6): if c!=a and c!=b: count+=1 print "第%d種:A分到書%d,B分到書%d,C分到書%d"%(count,a,b,c)
運行結果為:
假設五本書分別為1,2,3,4,5,主要借法有
第1種:A分到書1,B分到書2,C分到書3
第2種:A分到書1,B分到書2,C分到書4
第3種:A分到書1,B分到書2,C分到書5
第4種:A分到書1,B分到書3,C分到書2
第5種:A分到書1,B分到書3,C分到書4
第6種:A分到書1,B分到書3,C分到書5
第7種:A分到書1,B分到書4,C分到書2
第8種:A分到書1,B分到書4,C分到書3
第9種:A分到書1,B分到書4,C分到書5
第10種:A分到書1,B分到書5,C分到書2
第11種:A分到書1,B分到書5,C分到書3
第12種:A分到書1,B分到書5,C分到書4
第13種:A分到書2,B分到書1,C分到書3
第14種:A分到書2,B分到書1,C分到書4
第15種:A分到書2,B分到書1,C分到書5
第16種:A分到書2,B分到書3,C分到書1
第17種:A分到書2,B分到書3,C分到書4
第18種:A分到書2,B分到書3,C分到書5
第19種:A分到書2,B分到書4,C分到書1
第20種:A分到書2,B分到書4,C分到書3
第21種:A分到書2,B分到書4,C分到書5
第22種:A分到書2,B分到書5,C分到書1
第23種:A分到書2,B分到書5,C分到書3
第24種:A分到書2,B分到書5,C分到書4
第25種:A分到書3,B分到書1,C分到書2
第26種:A分到書3,B分到書1,C分到書4
第27種:A分到書3,B分到書1,C分到書5
第28種:A分到書3,B分到書2,C分到書1
第29種:A分到書3,B分到書2,C分到書4
第30種:A分到書3,B分到書2,C分到書5
第31種:A分到書3,B分到書4,C分到書1
第32種:A分到書3,B分到書4,C分到書2
第33種:A分到書3,B分到書4,C分到書5
第34種:A分到書3,B分到書5,C分到書1
第35種:A分到書3,B分到書5,C分到書2
第36種:A分到書3,B分到書5,C分到書4
第37種:A分到書4,B分到書1,C分到書2
第38種:A分到書4,B分到書1,C分到書3
第39種:A分到書4,B分到書1,C分到書5
第40種:A分到書4,B分到書2,C分到書1
第41種:A分到書4,B分到書2,C分到書3
第42種:A分到書4,B分到書2,C分到書5
第43種:A分到書4,B分到書3,C分到書1
第44種:A分到書4,B分到書3,C分到書2
第45種:A分到書4,B分到書3,C分到書5
第46種:A分到書4,B分到書5,C分到書1
第47種:A分到書4,B分到書5,C分到書2
第48種:A分到書4,B分到書5,C分到書3
第49種:A分到書5,B分到書1,C分到書2
第50種:A分到書5,B分到書1,C分到書3
第51種:A分到書5,B分到書1,C分到書4
第52種:A分到書5,B分到書2,C分到書1
第53種:A分到書5,B分到書2,C分到書3
第54種:A分到書5,B分到書2,C分到書4
第55種:A分到書5,B分到書3,C分到書1
第56種:A分到書5,B分到書3,C分到書2
第57種:A分到書5,B分到書3,C分到書4
第58種:A分到書5,B分到書4,C分到書1
第59種:A分到書5,B分到書4,C分到書2
第60種:A分到書5,B分到書4,C分到書3
下面我們把這個問題擴充一下,做一個更加通用的程式,就是將m本書分給n個小朋友,共中n<=m,要求每人每次只能分到一本。排列組合這個古老的問題解法有很多,這裡我們用的方法是先從m本書中取出n本,然後對n本進行排列。於是我們分步實現:
第一步,從m本書中取出n本,具體代碼:
# -*- coding: cp936 -*-'''對m個數中取n個的取法'''##@小五義 http://www.cnblogs.com/xiaowuyidef combination(lst,n): rst = [] if n == 1: for i in lst: l = [] l.append(i) rst.append(l) else: for i in combination(lst,n-1): for j in range(lst.index(i[-1])+1,len(lst)): l = i[:] l.append(lst[j]) rst.append(l) return rstif __name__ == "__main__": rst = []#記錄書的組合 lst=[]#將書編號 numlist=[]#記錄數組合後的數字 num=raw_input('輸入數的本數m:') for i in range(1,int(num)+1): lst.append(str(i)) print lst i=raw_input('輸入小朋友數量n:') ivrst = combination(lst,int(i)) rst = rst + ivrst for i in rst:#將得到的組合讀出 print i numstr='' for j in i:#將組合組成數字 numstr=numstr+j numlist.append(numstr) print numlist
第二步,對n本書進行排列,具體代碼:
# -*- coding: cp936 -*-'''對m個數進行排列'''##@小五義 http://www.cnblogs.com/xiaowuyiimport time,sysdef permute(num): l = len(num) if l <= 2: if l == 2: return [num,num[1],num[0],num[1]+num[0]] else: return [num] else: list = [] for i in range(len(num)): li = num[:i]+num[i+1:] #print 'li=',li for x in permute(li): p=num[i:i+1]+x list.append(p) return listnum = raw_input('the number:')list1 = permute(num)list1= [''.join(x) for x in list1 if len(x)==len(num)]print list1
最後,將前兩步合并,並將程式進行完善。
# -*- coding: cp936 -*-##@小五義 http://www.cnblogs.com/xiaowuyi'''借書方案:小明有m本新書,要借給n位小朋友,若每人每次只能借一本,則可以有多少種不同的借法。'''def combination(lst,n):#將lst中取出n個進行組合 rst = [] if n == 1: for i in lst: l = [] l.append(i) rst.append(l) else: for i in combination(lst,n-1): for j in range(lst.index(i[-1])+1,len(lst)): l = i[:] l.append(lst[j]) rst.append(l) return rstdef permute(num):#將書進行排列 l = len(num) if l <= 2: if l == 2: return [num,num[1],num[0],num[1]+num[0]] else: return [num] else: list = [] for i in range(len(num)): li = num[:i]+num[i+1:] #print 'li=',li for x in permute(li): p=num[i:i+1]+x list.append(p) return listif __name__ == "__main__": count=0 #記錄第幾種分法 rst = []#記錄書的組合 lst=[]#將書編號 numlist=[]#記錄數組合後的數字 num_bool=True #用來判斷小朋友數不大於書的數量 book_list=[]#記錄最後組合數 ##判斷小朋友數不大於書的數量 while num_bool: try: books=int(raw_input('小明一共有書的數量:')) baby=int(raw_input('要分給的小朋友數量(不大於書的數量)')) if baby>books or books==0 or baby==0: print'輸入錯誤,請重新輸入。' num_bool=True else: num_bool=False except: print'輸入錯誤,請重新輸入。' num_bool=True for i in range(1,books+1): lst.append(str(i)) books_com=combination(lst,baby) rst=rst+books_com for i in rst:#將得到的組合讀出 numstr='' for j in i:#將組合組成數字 numstr=numstr+j numlist.append(numstr) ##print numlist for i in numlist: list1=permute(i) ##book_list=[''.join(x) for x in list1 if len(x)==len(i)] for x in list1: if len(x)==len(i): book_list.append(x) for i in book_list: count+=1 print "第%d種:%s"%(count,i)
運行結果為:
小明一共有書的數量:5
要分給的小朋友數量(不大於書的數量)3
第1種:123
第2種:132
第3種:213
第4種:231
第5種:312
第6種:321
第7種:124
第8種:142
第9種:214
第10種:241
第11種:412
第12種:421
第13種:125
第14種:152
第15種:215
第16種:251
第17種:512
第18種:521
第19種:134
第20種:143
第21種:314
第22種:341
第23種:413
第24種:431
第25種:135
第26種:153
第27種:315
第28種:351
第29種:513
第30種:531
第31種:145
第32種:154
第33種:415
第34種:451
第35種:514
第36種:541
第37種:234
第38種:243
第39種:324
第40種:342
第41種:423
第42種:432
第43種:235
第44種:253
第45種:325
第46種:352
第47種:523
第48種:532
第49種:245
第50種:254
第51種:425
第52種:452
第53種:524
第54種:542
第55種:345
第56種:354
第57種:435
第58種:453
第59種:534
第60種:543
可以看出,下面的這個程式對第一程式進行了擴充,更加具有通用性。