腾讯机考——假期
问题描述
由于业绩优秀,公司给小Q放了 n 天的假,身为工作狂的小Q打算在在假期中工作、锻炼或者休息。他有个奇怪的习惯:不会连续两天工作或锻炼。只有当公司营业时,小Q才能去工作,只有当健身房营业时,小Q才能去健身,小Q一天只能干一件事。给出假期中公司,健身房的营业情况,求小Q最少需要休息几天。
输入描述:
第一行一个整数
表示放假天数
第二行 n 个数 每个数为0或1,第 i 个数表示公司在第 i 天是否营业
第三行 n 个数 每个数为0或1,第 i 个数表示健身房在第 i 天是否营业
(1为营业 0为不营业)
输出描述:
一个整数,表示小Q休息的最少天数
输入例子1:
4
1 1 0 0
0 1 1 0
输出例子:
2
例子说明1:
小Q可以在第一天工作,第二天或第三天健身,小Q最少休息2天
思路
通过题目描述,我们可以分析得出,小Q不会连续两天工作或者锻炼,但是会连续两天休息。所以我们可以画出状态转移图如下:
具体来说,工作的前一个状态一定是锻炼或者休息,锻炼的前一个状态一定是工作或者休息,而休息的前一个状态可能是休息,锻炼和工作。
我们在这里可以设S(state,n),state = 0,1,2,依次代表休息,工作和锻炼三种状态,你代表天数。表示第n天的状态为state时的最小休息天数。
举例来说,S(0,1)表示第1天小Q休息的条件下,小Q的最小休息天数。
我们可以推出以下递推公式:
休息:
S(0,i) = 1 + min(S(0,i-1), S(1,i-1), S(2,i-1))
工作:
当第 i 天可以工作时,S(1,i) = min(S(0,i-1), S(2,i-1))
当第 i 天不可以工作时,S(1,i) = 1 + min(S(0,i-1), S(2,i-1))
锻炼:
当第 i 天可以锻炼时,S(2,i) = min(S(0,i-1), S(1,i-1))
当第 i 天不可以工作时,S(2,i) = 1 + min(S(0,i-1), S(1,i-1))
这样我们就可以通过建立一个3*4表格来完成上述问题求解:
1 | 2 | 3 | 4 | |
0 | 1 | |||
1 | ... | |||
2 | ... |
代码实现如下:
n = int(input()) work = list(map(int,input().split())) exe = list(map(int,input().split())) choice = 3 # work = [1,1,0,0] # exe = [0,1,1,0] table = [[0 for column in range(n)] for row in range(choice)] table[0][0],table[2][0]=1,1 for j in range(1,n): table[0][j] = 1 + min(table[0][j-1],table[1][j-1],table[2][j-1]) if work[j] == 1: table[1][j] = min(table[0][j-1],table[2][j-1]) if work[j] == 0: table[1][j] = 1 + min(table[0][j-1],table[2][j-1]) if exe[j] == 1: table[2][j] = min(table[0][j-1],table[1][j-1]) if exe[j] == 0: table[2][j] = 1 + min(table[0][j-1],table[1][j-1]) # print(table) res = [table[0][n-1],table[1][n-1],table[2][n-1]] # print(res) print(min(res))