网络算法-小猪过河-python实现-动态规划-最长上升子序列

目录

一.问题叙述

二.研究报告

三.项目代码


一.问题叙述

N只小猪排成一个队列在沿河的公路上飞驰。现有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

二.研究报告

 

 

 

三.项目代码

from collections import  defaultdict
A=defaultdict(list)
def read_file(filepath,A):
    """"处理数据"""
    f=open(filepath,"r")
    test_num=int(f.readline().strip())
    for i in range(test_num):
        mid=[]
        for line in f.readline().split():
            A[i].append(int(line))
    return test_num



def erfenchazhao(data,left,right,key):
    """二分查找+返回替换位置"""
    if((right-left)==1):#data长度为1,直接返回
            if(data[left]>=key):
                return left
    else:
       mid=(left+right)//2
       if key<data[mid] and key>data[mid-1] and mid>=1:#找到在data(递增)中比第一个自己大的元素的位置返回
            return  mid
       else:
        if key<data[mid]:
             return erfenchazhao(data,left,mid,key)
        else:
             return erfenchazhao(data,mid+1,right,key)


def answer_problem(testdata):
    """动态规划+二分查找-求解"""
    B=[]#B[i-1]存储最长上升子序列为i序列的最小的最末元素
    B.append(testdata[0])
    for i in range(len(testdata)):
        if(testdata[i]>B[-1]):#比此时B的最后一个元素大,就加入
            B.append(testdata[i])
        else:#否则就二分而查找,找到第一个比自己小的元素
               index=erfenchazhao(B,0,len(B),testdata[i])
               B[index]=testdata[i]
    return len(B)


num=read_file('project7-test1',A)
for i in range(num):
    ans=answer_problem(A[i])
    print(ans)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个编程的菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值