小猪过河(通信网理论基础)
只小猪排成一个队列在沿河的公路上飞驰。现有n个入口,第i个入口唯一对应河对岸的第j个出口。小猪队列在经过第i个入口时可以选择过河与否,若选择过河,则队首的一只小猪去到对岸第j个出口。要求经过了n个入口后,河对岸小猪的相对顺序与原队列相同(倒序)。求最大过河小猪数。
如图:输入为(4,2,6,1,3,5)表示第一个入口对应第4个出口,第二个入口对应第二个入口,等等。
情况1表示,选择了所有入口进入,导致河对岸的小猪相对顺序与原队列不同。
情况2表示,只选择了2,5,6号入口进入,河对岸小猪的相对顺序与原队列相同,同时河对岸小猪数量最大。(在4,5,6号入口进入也是3)
输入:第一行为正整数t,表示t个测试用例。之后t行,每行m<20000个正整数,其中第i个正整数j表示第i个入口对应第j个出口。
输出:每个用例输出一行,该行有一个正整数,表示最大河对岸小猪数。
样例:
输入:
3
4 2 6 1 3 5
1 2 3 4 5 6 7
8 7 6 5 4 3 2 1
2 8 1 5 6 4 3 8 9
输出:
3
7
1
5
题目分析:
该问题为最长上升子序列问题。
贪心+二分的算法。
def FindLIS(k):
l=list()
l.append(eval(k[0]))
for i in k:
flag= 0
for j in range(len(l)):
if eval(i)<= l[j]:
l[j]=eval(i)
flag=1
break
if flag==0:
l.append(eval(i))
print(len(l))
if __name__ == '__main__':
fo= open('D:/小猪过河/测试数据1.txt', 'r')
count= fo.readline()
print("测试用例数量为:{}".format(count))
for i in range(eval(count)):
k= fo.readline().split()
FindLIS(k)