题目描述
“汉诺塔”是一个众所周知的古老游戏。
现在我们把问题稍微改变一下:如果一共有4根柱子,而不是3根,那么至少需要移动盘子多少次,才能把所有的盘子从第1根柱子移动到第4根柱子上呢?
为了编程方便,您只需要输出这个结果mod 10000的值。
输入
该题含有多组测试数据,每组一个正整数n。(0<n<=50000)
输出
一个正整数,表示把n个盘子从第1根柱子移动到第4根柱子需要的最少移动次数mod 10000的值。
样例输入
15
样例输出
129
题目思路:
再思考过程中,此题需要与三塔汉诺塔联系起来,熟悉三塔汉诺塔的模型不难推出n个圆盘所需移动次数为f[n] = 2 * f[n-1] + 1,且f[1] = 1。那么在四塔汉诺塔中,我们假定四塔汉诺塔n个圆盘所需移动次数为dp[n],那么我们先将j个圆盘通过四塔移动到B或者C塔上,次数为dp[j],对剩下的n-j个圆盘通过三塔移动次数放在D上,次数为f[n-j],因为n-j个圆盘皆为大圆盘,所以对接下来的圆盘移动不会造成影响,剩下j个圆盘则用四塔方法挪动至D塔上,次数为dp[j],所以n个圆盘的四塔汉诺塔所需移动次数为f[n-j] + 2*dp[j]。然后用暴搜法查找到最佳的j为多少。
f = [0 for i in range(1005)]
dp = [100000 for i in range(1005)]
while(True):
n = int(input())
for i in range(1,n+1):
f[i] = 2*f[i-1] + 1
dp[1] = 1
for i in range(n+1):
for j in range(1,i):
dp[i] = min(dp[i],(f[i-j]+2 * dp[j]))
print(dp[n])
但是:
想要通过这种方法在OJ上完成这道题是不可行的,python容易内存撑爆导致运行错误,建议先用上方方法测试多组样例数据,找出规律,优化代码。下方为复杂度为O(n)的该题算法:
while(True):
n = int(input())
temp, f, cnt, ans = 0,1,1,2
for i in range(1, n+1):
temp = (temp + f) % 10000
if cnt == i:
cnt += ans
ans += 1
f = (f*2) %10000
print(temp)
题目描述
今天,TC买了一盒火柴,打算和小yh比拼谁能用有限的火柴得到一个最大数字。火柴拼数字规则是,拼出零到九分别需要6、2、5、5、4、5、6、3、7、6个火柴。
现在给TC a个不同火柴数,求你帮TC计算不同的火柴数a分别能组成的最大数字,如果不能组成数字,输出-1。
输入
第一行输入一个n。
接下来n行,每行一个数a(0<=a<=103)
输出
每行输出一个能组成的最大数字。
样例输入
3 1 2 4
样例输出
-1 1 11
提示
TC说火柴要省着用
题目解析:
贪心算法,要组成最大数字,当然是位数越多越大,所需火柴最小的数字是1,其次是7,其余消耗火柴太大,所以只需判断火柴数是否是2的倍数,如果是则全部组成1,如果不是则把剩余一根和第一个1组成替换成7,其余全部组成1
def judge():
ans = int(a/2)
if ans == 0:
print(-1)
else:
if a%2 == 0:
print(1,end = '')
else:
print(7,end = '')
for i in range(int(ans)-1):
print(1,end = '')
print()
while(True):
n = int(input())
for i in range(n):
a = int(input())
judge()
break