1.2.1 Longest rising subsequence model (1)

1. The longest ascending subsequence

Given a length of NNFor an array of N , find the longest length of a subsequence whose values ​​strictly increase monotonically.

Input format
The first line contains the integer N.

The second line contains N integers, representing the complete sequence.

Output format
Output an integer indicating the maximum length.

Data range
1 ≤ N ≤ 1000, 1≤N≤1000,1N1000 ,
− 1 0 9 ≤ sequence neutral number ≤ 1 0 9 −10^{9}≤ sequence neutral number ≤10^{9}109sequence neutral number109

Input example:

7
3 1 2 1 8 5 6

Output sample:

4

Solution
Insert image description here
code

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1010;

int n;
int a[N];//序列
int f[N];//状态

int main()
{
    
    
    scanf("%d",&n);
    for(int i = 1; i <= n;i++)  scanf("%d",&a[i]);
    
    for(int i = 1; i <= n;i++)
    {
    
    
        f[i] = 1;//只有i一个数a[i]
        for(int j = 1;j < i;j++)
            if(a[j] < a[i])
                f[i] = max(f[i],f[j] + 1);
    }
    
    int res = 0;
    //枚举所有终点
    for(int i = 1; i <= n;i++) res = max(res,f[i]);
    
    printf("%d",res);
    
    return 0;
}

2. Kaitou Kidd’s Glider

Kaito Kidd is a legendary thief, a super thief who specializes in jewelry.

The most outstanding thing about him is that he can escape the heavy encirclement of the Nakamura Police Department every time, and this is largely due to the easy-to-operate hang glider he carries with him.

One day, Kaitou Kidd stole a precious diamond as usual, but his disguise was discovered by Conan's children, and the power device of his glider was also destroyed by the football kicked by Conan.

As a last resort, Kaito Kidd can only use the damaged glider to escape.

Suppose there are N buildings in a line in the city, and each building has a different height.

Initially, Kaito Kidd can be on top of any building.

He can choose a direction to escape, but cannot change direction midway (because the Nakamori Police Department will pursue him).

Because the glider's power unit was damaged, he could only glide downwards (that is, he could only glide from a higher building to a lower building).

He wanted to pass over the tops of as many different buildings as possible, which would slow down the impact of the descent and reduce the likelihood of injury.

Please tell me, how many tops of different buildings can he pass at most (including the initial building)?

Input format
The first line of input data is an integer KKK , stands forKKK group of test data.

Each set of test data contains two lines: the first line is an integer NNN means there are N buildings. The second row containsNNN different integers, each corresponding to the height h of a building, are given in the order in which the buildings are arranged.

Output format
For each set of test data, output one line, containing an integer, representing the maximum number of buildings that Kaitou Kidd can pass.

Data range
1 ≤ K ≤ 100, 1≤K≤100,1K100,
1 ≤ N ≤ 100 , 1≤N≤100, 1N100,
0 < h < 10000 0<h<10000 0<h<10000

Input example:

3
8
300 207 155 299 298 170 158 65
8
65 158 170 298 299 155 207 300
10
2 1 3 4 5 6 7 8 9 10

Output sample:

6
6
9

Problem solving
Insert image description here
code implementation

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 110;

int n;
int a[N],f[N];

int main()
{
    
    
    int T;
    scanf("%d",&T);
    while(T--)
    {
    
    
        scanf("%d",&n);
        for(int i = 1;i <= n;i++)   scanf("%d",&a[i]);
        
        //正向求解LTS问题
        int res = 0;
        for(int i = 1;i <= n;i++)
        {
    
    
            f[i] = 1;
            for(int j = 1;j < i;j++)
                if(a[i] > a[j])
                    f[i] = max(f[i],f[j] + 1);
            res = max(res,f[i]);
        }
        
        //反向求解LTS问题
        for(int i = n;i;i--)
        {
    
    
            f[i] = 1;
            for(int j = n;j > i;j--)
                if(a[i] > a[j])
                    f[i] = max(f[i],f[j] + 1);
            res = max(res,f[i]);
        }
        
        printf("%d\n",res);
    }
    
    return 0;
}

3. Climbing

On May Day, the ACM team organized everyone to go mountaineering and sightseeing. The team members found that there were a total of N scenic spots on the mountain, and decided to browse these scenic spots in order, that is, the number of each scenic spot visited must be greater than the number of the previously visited scenic spot.

At the same time, the team members also have another mountaineering habit, which is not to visit two scenic spots with the same altitude continuously, and once they start going down the mountain, they will not go up.

The team members hope to visit as many scenic spots as possible while meeting the above conditions. Can you help them find the maximum number of scenic spots they can visit?

Input format
The first line contains the integer NNN , represents the number of attractions.

The second row contains NNN integers, representing the altitude of each scenic spot.

Output format:
Output an integer, indicating the maximum number of scenic spots that can be browsed.

Data range
2 ≤ N ≤ 1000 2≤N≤10002N1000
input example:

8
186 186 150 200 160 130 197 220

Output sample:

4

Solution:
Insert image description here
Climbing a mountain is to add the left and right sides, and Kaito Kid's hang glider is to find the maximum value of the left and right sides.
code

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1010;

int n;
int a[N];
int f[N],g[N];

int main()
{
    
    
    scanf("%d",&n);
    for(int i = 1; i <= n;i++)  scanf("%d",&a[i]);
    
    //从左到右求f
    for(int i = 1;i <= n;i++)
    {
    
    
        f[i] = 1;
        for(int j = 1;j < i;j++)
            if(a[i] > a[j])
                f[i] = max(f[i],f[j] + 1);
    }
    //从右到左求g
    for(int i = n;i;i--)
    {
    
    
        g[i] = 1;
        for(int j = n;j > i;j--)
            if(a[i] > a[j])
                g[i] = max(g[i],g[j] + 1);
    }
    
    int res = 0;
    for(int i = 1;i <= n;i++)   res = max(res,f[i] + g[i] - 1);
    
    printf("%d\n",res);
    
    return 0;
}

4.Chorus formation

N N N students stand in a row, and the music teacher wants to invite(N − K) (N−K)(NK ) students come out of the queue, so that the remainingKKK students formed a chorus formation.

The chorus formation refers to such a formation: Suppose KKK students are numbered from left to right as1, 2..., K 1, 2..., K12, K , their heights areT 1 , T 2 , ... , TK T_{1}, T_{2}, ..., {T}_{K}T1T2TK, then their height satisfies T 1 < … < T i > T i + 1 > … > TK ( 1 ≤ i ≤ K ) T_{1}<…<T_{i}>T_{i+1}>…> T_{K}(1≤i≤K)T1<<Ti>Ti+1>>TK(1iK)

Your task is to know all NNThe height of N students is calculated by calculating the minimum number of students needed to line up so that the remaining students can form a chorus formation.

Input format
The first line of input is an integer NNN , represents the total number of classmates.

The second row has NNN integers, separated by spaces,iii integersT i T_{i}TiThis is number iiThe height of i classmate (cm).

Output format
The output includes one line. This line only contains an integer, which is the minimum number of students required to queue up.

Data range
2 ≤ N ≤ 100, 2≤N≤100,2N100,
130 ≤ T i ≤ 230 130≤T_{i}≤230 130Ti230
input example:

8
186 186 150 200 160 130 197 220

Output sample:

4

Solution to the problem
is similar to mountain climbing, except that the output
code of the code is modified.

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 110;

int n;
int a[N];
int f[N],g[N];

int main()
{
    
    
    scanf("%d",&n);
    for(int i = 1; i <= n;i++)  scanf("%d",&a[i]);
    
    //从左到右求f
    for(int i = 1;i <= n;i++)
    {
    
    
        f[i] = 1;
        for(int j = 1;j < i;j++)
            if(a[i] > a[j])
                f[i] = max(f[i],f[j] + 1);
    }
    //从右到左求g
    for(int i = n;i;i--)
    {
    
    
        g[i] = 1;
        for(int j = n;j > i;j--)
            if(a[i] > a[j])
                g[i] = max(g[i],g[j] + 1);
    }
    
    int res = 0;
    for(int i = 1;i <= n;i++)   res = max(res,f[i] + g[i] - 1);
    
    printf("%d\n",n - res);
    
    return 0;
}

5. Sister cities

There is a large river in Palmia that runs from east to west. The river has straight north and south banks. There are NNs with different positions on each bank.N cities.

Each city on the North Bank has only one sister city on the South Bank, and different cities have different sister cities.

Each pair of sister cities applied to the government to open a straight channel on the river to connect the two cities. However, due to too much fog on the river, the government decided to avoid any two channels crossing to avoid accidents.

Programming helps the government make some decisions about approving and rejecting applications, so that as many applications as possible can be approved while ensuring that any two routes do not intersect.

Input format
No. 1 11 row, an integerNNN , represents the number of cities.

2nd 2ndLine 2 ton+1 n+1n+1 line, two integers in each line,1 1Separated by 1 space, they represent the coordinates of a pair of sister cities on the south bank and the north bank respectively.

Output format:
Only one line, output an integer, indicating the maximum number of applications that the government can approve.

Data range
1 ≤ N ≤ 5000, 1≤N≤5000,1N5000,
0 ≤ x i ≤ 10000 0≤x_{i}≤10000 0xi10000
input example:

7
22 4
2 6
10 3
15 12
9 8
17 17
4 2

Output sample:

4

answer

Insert image description here
step

1. Fix the order of independent variables through sorting

2. Find the largest rising subsequence of the dependent variable

Insert image description here
Because the waterways cross

city1.first < city2.first, 但是city1.second > city2.second

So sort one bank and find the longest ascending subsequence on the other bank

code

#include<iostream>
#include<algorithm>

using namespace std;

typedef pair<int,int> PII;
const int N = 5010;

int n;
PII q[N];
int f[N];

int main()
{
    
    
    scanf("%d",&n);
    for(int i = 0;i < n;i++)    scanf("%d%d",&q[i].first,&q[i].second);
    sort(q,q + n);
    
    int res = 0;
    for(int i = 0;i < n;i++)
    {
    
    
        f[i] = 1;
        for(int j = 0;j < i;j++)
            if(q[i].second > q[j].second)
                f[i] = max(f[i],f[j] + 1);
                
        res = max(res,f[i]);
    }
    
    printf("%d",res);
    
    return 0;
}

6. Maximum rising subsequence sum

Sequence of numbers bi b_{i}bi,当 b 1 < b 2 < … < b S b_{1}<b_{2}<…<b_{S} b1<b2<<bSWhen , we call this sequence ascending.

For a given sequence (a 1, a 2, …, a N) (a_{1},a_{2},…,a_{N})(a1,a2,,aN) , we can get some ascending subsequences(ai 1, ai 2, …, ai K) (a_{i1},a_{i2},…,a_{iK})(ai 1,ai2,,ai K),这里 1 ≤ i 1 < i 2 < … < i K ≤ N 1≤i_{1}<i_{2}<…<i_{K}≤N 1i1<i2<<iKN

For example, for the sequence (1, 7, 3, 5, 9, 4, 8) (1,7,3,5,9,4,8)(1,7,3,5,9,4,8 ) , there are some ascending subsequences of it, such as(1, 7) (1,7)(1,7), ( 3 , 4 , 8 ) (3,4,8) (3,4,8 ) Wait.

The maximum sum of these subsequences is 18 1818 , which is the subsequence(1, 3, 5, 9) (1,3,5,9)(1,3,5,9 ) and.

Your task is to find the maximum sum of ascending subsequences for a given sequence.

Note that the sum of the longest ascending subsequence is not necessarily the largest, such as the sequence (100, 1, 2, 3) (100,1,2,3)(100,1,2,3 ) The maximum rising subsequence sum is 100, and the longest rising subsequence is(1, 2, 3) (1,2,3)(1,2,3)

Input format
The first line of input is the length of the sequence NNN

The second line gives the NN in the sequenceN integers, the value range of these integers is0 00 to10000 1000010000 (possible duplicate).

Output format
Output an integer representing the maximum ascending subsequence sum.

Data range
1 ≤ N ≤ 1000 1≤N≤10001N1000
input example:

7
1 7 3 5 9 4 8

Output sample:

18

The difference between the solution
Insert image description here
and the longest ascending subsequence is that it will +1be changed to+a[i]

code

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1010;

int n;
int a[N];//序列
int f[N];//状态

int main()
{
    
    
    scanf("%d",&n);
    for(int i = 1; i <= n;i++)  scanf("%d",&a[i]);
    
    for(int i = 1; i <= n;i++)
    {
    
    
        f[i] = a[i];//只有i一个数a[i]
        for(int j = 1;j < i;j++)
            if(a[j] < a[i])
                f[i] = max(f[i],f[j] + a[i]);
    }
    
    int res = 0;
    //枚举所有终点
    for(int i = 1; i <= n;i++) res = max(res,f[i]);
    
    printf("%d",res);
    
    return 0;
}

Guess you like

Origin blog.csdn.net/m0_51366201/article/details/131752115