2020-08-30 20:15:35
我分别用穷举和回溯两种算法来实现这个功能,代码如下:
#穷举法:直接用位运算操作整数t的各个二进制数位,效率更高
def divide_stones_4(a, n):
total = sum(a)
half = total // 2
max_s = 0
lib = tuple(map(lambda x: 1 << x, range(n-1,-1,-1)))#从高到低标记每个二进制位的1
for t in range(1<
s = 0
for i in range(n):
if t & lib[i] > 0: #t的二进制数第i位是1,则选择该堆石子
s += a[i] #累计被选中的石子堆的数量
if max_s < s <= half: #更新最优解
max_s = s
return total - max_s * 2 #返回最小差值
#深搜算法:直接用位运算操作整数t的各个二进制数位,每层递归函数的选择模式都继承自上一层函数,每层只选择1堆石子
def divide_stones_5(a, n):
total = sum(a)
half = total // 2
max_s = 0
lib = tuple(map(lambda x: 1 << x, range(n-1,-1,-1)))#从高到低标记每个二进制位的1
def dfs(t, s): #参数:t,正整数,其二进制数代表当前选择模式;s,正整数,表示已经选择的石子数量。
nonlocal max_s
if s > max_s: #更新最优解
max_s = s
for i, bit in enumerate(lib):
if t & bit == 0: #只在第一个值为1的二进制位左侧设置1,以避免重复
if s+a[i] <= half: #已经超出半数就无需再选择新的石子堆了
t |= bit #将整数t的第i个二进制位设置成1
dfs(t, s+a[i])
t &= ~bit #将整数t的第i个二进制位恢复成0
else:
break
dfs(0, 0)
return total - max_s * 2 #返回最小差值
在穷举算法中,无论是用列表b来模拟一个整数t的n位二进制数,还是用位运算直接操作整数t的各个二进制位,都是非常巧妙的方法,每当遇到这种题目,都有令人眼前一亮的感觉。无独有偶,我有幸遇到了与“石子划分问题”很相似的一道题目,与大家共同分享。
题目:翻转棋子游戏
难度:3星 有趣:3星 有用:3星
分类:穷举,深搜,广搜
描述:翻转棋子游戏是这样玩的:
有一张4*4的棋盘,在16个位置上每个位置放着一个棋子,棋子一面是黑色,另一面是白色,棋子或者白色面朝上,或者黑色面朝上。
游戏的走法如下:每一步先选择一个位置,然后把该位置和上,下,左,右(不越界)相邻位置上的棋子翻转(白->黑,黑->白)。
我们用一个长度为16的字符串board存储棋盘上每颗棋子的颜色状态,每颗棋子的颜色可以用0、1来表示,0表示白,1表示黑,顺序为从左至右,从上至下。
例如,board="1011000111110001",表示的棋盘状态如下:
1010
0000
1101
1001
当我们选择第三行,第一列的位置翻转时,棋盘变化为:
1010
1000
0001
0001
游戏的目的是用最少的步数把全部棋子变为白色向上或黑色向上。
函数:flip_chess(board)
参数说明:board -- 长度为16的字符串,存储了棋盘上每颗棋子的初始颜色状态。
返回值:返回最少的翻转次数,如果无法翻转成目标状态,则输出"impossible"。
样例1: board="1010000011011001",返回"impossible";
样例2: board="1001110110011000",返回4。
算法分析:
初看本题,最容易想到的是穷举法,用包含16个元素的列表d分别表示每个棋子的翻转状态,d[i]=1表示翻转第i个棋子,d[i]=0表示不翻转。
可以穷举从d=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]到d=[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],即从都不翻转到都翻转。若把列表d对应整数t的16位二进制数,则相当于穷举从t=0到t=2^16-1。
我们可以直接用位运算操作整数t的各个二进制数位,从而生成整数t对应的棋盘翻转模式,判断该模式是否有解。若该翻转模式能获得更好的解,则更新最优解。
本题的各种算法也可以用c++语言来实现,两种语言相比较,我发现由于Python语言的自动回收内存机制和函数式编程特征,以及丰富的内置函数,使得编程者无需考虑过多的实现细节,能更关注算法思想本身,代码也更简洁,更优雅。
----------------------------------------------
相关文章
更多文章
.