Test question algorithm training swing sequence (Lanqiao Cup C/C++)

**

Test question algorithm training swing sequence

**

Resource limitation
Time limitation: 1.0s Memory limitation: 512.0MB
Problem description
  If a sequence satisfies the following properties, we call it a swing sequence:
  1. All numbers in the sequence are positive integers not greater than k;
  2. Sequence There are at least two numbers in.
  3. The numbers in the sequence are not equal;
  4. If the i – 1 number is greater than the i – 2 number, the i number is smaller than the i – 2 number; if the i – 1 number If the number is smaller than the i-2th number, the i-th number is larger than the i-2th number.
  For example, when k = 3, there are several such sequences:
  1 2
  1 3
  2 1
  2 1 3
  2 3
  2 3 1
  3 1
  3 2
  There are 8 kinds in total, given k, request a sequence that meets the above requirements The number of.
Input format
  input contains an integer k. (K<=20)
Output format
  outputs an integer, indicating the number of sequences that meet the requirements.
Sample input
3
Sample output
8

Foreword:

The blogger is a sophomore rookie, preparing for the Blue Bridge Cup during the holiday, writing a blog for the first time, hoping to share what I have learned in the blog, and then share what I have learned with everyone in a way that I understand. , Everyone can correct me if there are deficiencies, and learn more with the big guys!

Thoughts and ideas:

First of all, the idea of ​​this question is dp dynamic programming . The so-called dynamic programming is the process of solving the optimization process of the decision-making process. It is often to directly calculate the answer instead of getting the process of each step.

This question cannot be thought of with the idea of ​​traversal. For example, if you plan to traverse the sequence of each situation, and then if meets a certain form of count++, it must not work. If the data is too large, it will time out or the efficiency is too low and it is very complicated.

Dynamic programming will use two-dimensional arrays, and multiple loops are needed to solve the problem. In this problem, we will use a two-dimensional array dp[20][20] to store the results. The meaning of the array will be discussed below.

So how do you get started with this question?
1. From the question stem, we can know that the number of digits in each sequence must be greater than or equal to 2 and less than or equal to k.
Example: When k = 3, the sequence can be 1 2 of 2 or 3 1 3 2 (The maximum value in the sequence cannot be greater than k and at least two numbers)

2. Then we can write down the sequence situation when k is small and find some rules and ideas (this is often the essence of some algorithmic problems)

When k = 2, there are only 2 sequences: 12 or 21

When k = 3, the number 2 sequence: 12, 13, 21, 23, 31, 32 six kinds, the
number 3 sequence has 213, 231 two kinds

When k = 4, there are 12, 13, 14, 21, 23, 24, 31, 32, 34, 41, 42, and 43 sequences with a quantity of 2

There are 8 sequences with a quantity of 3: 213,214,314,324,231,241,341,342
(it is not difficult for us to find that the number of small size and large size is the same)

There are two sequences with a quantity of 4: 2314 and 3241 (one for large and small)

Then we summarize this result as the following figure:

(The ordinate represents the value of k, and the abscissa represents the number of the sequence of n numbers under the current k)

law
Then we can draw the law:
1. There are a total of 2 sequences with the number of numbers: k * (k-1) kinds

 			if(j == 2)
            {
    
    
                dp[i][j] = i * (i - 1);
            }

2. There are 2 kinds of diagonals

else if(j == i)
            {
    
    
                dp[i][j] = 2;
            }

3. In other cases, dp[i][j] = dp[i-1][j-1] + dp[i-1][j];

else
            {
    
    
                dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
            }

4, let me explain a two-dimensional array dp [i] [j] meaning, i represents the value of k, j represents the number of digits in the sequence
, so we thought this problem is to get results in all cases have to k Come out, i = 2, 3, 4, 5, 6..., and then directly find the value of dp[k][j] when i == k and add up each value and then cout.

for(int j=2;j<=k;j++)
    {
    
    
        answer+=dp[k][j];	//answer累加每一种的情况的数量
    }

The complete code is attached below:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include<string.h>

using namespace std;

int main( )
{
    
    
	int k,ans=0;
	int dp[21][21];
	memset(dp,0,sizeof(dp));        //初始化数组
	cin>>k;
	int i,j,x;
	for(i=2;i<=k;i++)           //  i : k=?的情况,最少两个数字组成序列,所以i=2开始,最大不能大于k
    {
    
    
        for(j=2;j<=i;j++)       //  j : 序列有多少个数字,最少是两个所以是j=2开始
        {
    
    
            if(j == 2)          //两个数字的情况
            {
    
    
                dp[i][j] = i * (i - 1);     
            }
            else if(j == i)     ///对角线的情况
            {
    
    
                dp[i][j] = 2;
            }
            else                ///其他情况的时候
            {
    
    
                dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
            }
        }
    }
    for(x=2;x<=k;x++)       ///输出答案
    {
    
    
        ans+=dp[k][x];		//在k的情况下,相加每一种数量数字的种类
    }
    cout << ans;			//输出答案
	return 0;
}

Execution result:
Insert picture description here
checking calculation: (52 == 20 + 20 + 10 + 2)

Afterword: There is another solution to this question: greedy, etc. If you want to know, you can go to other big guys to learn haha. The first time you write a blog, there are definitely many shortcomings. Communicate with everyone!

Guess you like

Origin blog.csdn.net/Kyrie_irving_kun/article/details/113618572