您的位置:首页 > 编程语言 > Python开发

网易2018校园招聘:合唱 [python]

2017-11-19 11:48 260 查看
'''

[编程题] 合唱

时间限制:2秒

空间限制:131072K

小Q和牛博士合唱一首歌曲,这首歌曲由n个音调组成,每个音调由一个正整数表示。

对于每个音调要么由小Q演唱要么由牛博士演唱,对于一系列音调演唱的难度等于所有相邻音调变化幅度之和, 

例如一个音调序列是8, 8, 13, 12, 那么它的难度等于|8 - 8| + |13 - 8| + |12 - 13| = 6(其中||表示绝对值)。

现在要对把这n个音调分配给小Q或牛博士,让他们演唱的难度之和最小,请你算算最小的难度和是多少。

如样例所示: 小Q选择演唱{5, 6}难度为1, 牛博士选择演唱{1, 2, 1}难度为2,难度之和为3,这一个是最小难度和的方案了。 

输入描述:

输入包括两行,第一行一个正整数n(1 ≤ n ≤ 2000) 第二行n个整数v[i](1 ≤ v[i] ≤ 10^6), 表示每个音调。

输出描述:

输出一个整数,表示小Q和牛博士演唱最小的难度和是多少。

输入例子1:

5

1 5 6 2 1

输出例子1:

3

'''

'''

解题思路:动态规划

  用字典d{[j,i]=xxx},其中j=-1,0,1,....,i-1,即d{[-1,i]=xxx,[0,i]=xxx,……,[i-1,i]=xxx}

  来表示在前i个音符中,一个人最后一次唱是唱j音符,剩下j+1到i的音符都由另一个人唱的难度和,

  若j=-1,则表示一个人唱完所有音符

  那么这个问题就可以利用动态更新字典d来解决

  在更新字典时候,分两种情况更新:

    1、唱最后一个音符时换人

    2、唱最后一个音符时不换人

'''

'''

代码运行结果:

答案正确:恭喜!您提交的程序通过了所有的测试用例

'''

num = int(input())
tones = [i for i in map(int, input().split())]

def _min(n, v):
d = {(-1, 0): 0}
for i in range(1, n):
_d = {}
for j in range(-1, i-1):
_d[(j, i)] = d[(j, i-1)] + abs(v[i] - v[i-1])
_d[i-1, i] = min([d[(k, i-1)] + abs(v[i]-v[k]) for k in range(i-1)] + [d[(-1, i-1)]])
del d
d = _d
return min([d[i, n-1] for i in range(-1, n-1)])

print(_min(num, tones))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息