题目要求:
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
YBH数学很差,她数数时分不清4,5和8;我们定义YBH[i]为YBH的计数法对应的i的值。
规定:YBH[4] = 5,YBH[5] = 8;YBH[i]运算规则如下:
① YBH[i+j] = YBH[i] + YBH[j]
② YBH[i*j] = YBH[i] * YBH[j]
我们会发现,用不同方法算出的YBH[i]的值是不同的,例如:当i=20时,
YBH[20] = 5*YBH[4] = 25;
YBH[20] = 4*YBH[5] = 32;
YBH[20] = YBH[4] * YBH[5] = 40;
......
我们规定:F[i]为YBH[i]的最大值,现在请你编写一个程序,输入一个数n,输出F[n]的值,若F[n]没有意义,输出-1。
输入格式
一个数n(8 <= n <= 1000)
输出格式
输出F[n]的值.
样例输入
20
样例输出
40
样例输入
11
样例输出
-1
数据规模和约定
8 <= n <= 1000
分析:
题目给的标签是DP,按照DP一般的解题思路进行分析即可。
1.定义数组并确定其元素的含义。
到底定义一维或是二维数组,这要看具体的题目再分析。根据这道题,我们可以定义一个一维数组,YBH[i],数组中存的值就是题目所求的最大值。
2.找到数组元素之间的关系。
首先题目中指出了如何得到YBH[i]:YBH[i+j] = YBH[i] + YBH[j] ,YBH[i*j] = YBH[i] * YBH[j],并且初始的YBH中仅有YBH[4],YBH[5],所以说YBH[i]存在的条件即为 i = 4*x + 5*y 。或者能不能找到在一个界限后所有的YBH都有意义。YBH中下标4和5有意义,那么我们把4,5减去4,这样一来,便可得到4 = 0 ,5 = 1,而有了1,便可以用加得到任意数。所以我们可以找到YBH存在,且连续的4个数,这样我们便可通过这个4个数去加4或者5,得到后面的所有数,这样一来我们可以不用判断后面的YBH是否有意义。这一组连续的4个数可以通过简单的计算得到:16,17,18,19。所以在i>16后,我们便不用判断YBH是否有意义。
接下来,我们来获得YBH[i]的最大值,的YBH[i]有两种方式可以得到。
1:乘法不能得到 i ,只能通过加法,所以 YBH[i] = YBH[i-4]+YBH[4], 或者YBH[i] = YBH[i-5]+YBH[5] ,我们只需求其中最大值即可。
2:乘法可以得到 i 。所以YBH[i]增加了一种得到的方式,即YBH[i] = YBH[i / 4] * YBH[4] 或者 YBH[i] = YBH[i / 5] * YBH[5]。当然乘法能得到加法一样可以得到,我们一起判断取最大值即可。
3.确定初始值。题目已经给了两个初值,YBH[4] = 5 , YBH[5] = 8
写代码:
n = int(input())
YBH = [0 for i in range(n + 1)]
if n >= 8 and n <= 1000:
for i in range(1, n + 1):
if i < 16:
if i < 6:
if i == 4:
YBH[i] = 5
elif i == 5:
YBH[i] = 8
else:
YBH[i] = -1
else:
if i % 4 == 1 or i % 5 == 4:
YBH[i] = max(YBH[i - 4] + 5, YBH[i - 5] + 8)
else:
YBH[i] = -1
else:
if i % 4 == 0 and i % 5 == 0:
YBH[i] = max(YBH[i // 4] * YBH[4], YBH[i // 5] * YBH[5], YBH[i - 4] + 5, YBH[i - 5] + 8)
elif i % 4 == 0 and i % 5 != 0:
YBH[i] = max(YBH[i // 4] * YBH[4], YBH[i - 4] + 5, YBH[i - 5] + 8)
elif i % 4 != 0 and i % 5 == 0:
YBH[i] = max(YBH[i // 5] * YBH[5], YBH[i - 4] + 5, YBH[i - 5] + 8)
else:
YBH[i] = max(YBH[i - 4] + 5, YBH[i - 5] + 8)
print(YBH[n])