Fluctuation series, simple AC code, detailed explanation.

Posted by wha??? on Sat, 20 Nov 2021 18:51:25 +0100

Wave series

This problem really takes time to understand the details.

Idea:

As shown in the figure below, the first item of the sequence is x, the tolerance is set, set={a, - b};

From the first picture below, we can know that the number of set s is n*(n-1)/2 (formula: first term plus last term divided by 2)

We let cnt=n*(n-1)/2 (that is, the number of set s). Through these analyses, we can know that the following condition is satisfied: sequence sum = Sn=nx+cntset

We assume that the number of a is num1, because the sum of the numbers of a and B is CNT, then the number of B is CNT num1; An expression NX + A * num1-b (CNT num1) = s can be derived; Change the position, that is, n * x=s-anum1+b(cnt-num1);. As we said above, the maximum number of sets is n (n-1) / 2. set has two possibilities: A and B. if it is all a, that is, there are at most n*(n-1)/2 a (0 B at this time), it will be easy to know this formula, because there are only two unknowns X and num1 in the formula, and we said that the upper limit of num1 (that is, the number of a) is n*(n-1)/2. We only need to enumerate this n*(n-1)/2. Carry out a for loop and find out the value that meets the conditions. After knowing the num1 that meets the conditions, we will naturally know the value of X. after that, let's introduce the following code, and I will directly type the comments in the code.

    int ans=0;//Used to record the number of times the condition is met.
	int cnt=n*(n-1)/2;		//Sum of a and b quantities.
    for(int i=0;i<=cnt;i++)	//In fact, all possible quantities of a are enumerated from 0. As long as x is an integer, it means that this quantity of a is qualified at this time.
    {
        long long h=s-i*a+(cnt-i)*b;
        //First of all, you need to know the meaning of this code. Combined with the above formula, you can know that h here represents even n*x; that is why there is a lower if judgment
        if(h%n==0)//The meaning of this judgment is to express that as long as the calculated x is an integer, the number of a at this time satisfies the condition.
            ans+=f[i];//I will introduce f[i] here below. Anyway, I just need to know that the number of I in this for loop is the number of a, and f[i] indicates the combination satisfied by the current number of A. you may not understand what combination I am talking about here. I will introduce it below
    }
Serial numberCorresponding value
0x
1x+set
2x+set+set
......
n-1x+(n-1)*set

Case 1:

Serial numberCorresponding value
1x
2x+a
3x+a-b
4x+a-b+a
5x+a-b+a+a
the sum5x+7a-3b

The number of a is 7, which is composed of 4 + 2 + 1

Case 2:

Serial numberCorresponding value
1x
2x+a
3x+a+a
4x+a+a-b
5x+a+a-b-b
the sum5x+7a-3b

The number of a is 7, but it is composed of 4 + 3, and the corresponding number of b is 3, which is composed of 2 + 1.

Let's look at these two cases. Although there are seven a's, it's not possible that they have different permutations. The most important details are here. Although we can find the number of a through that step over there, we don't know the combination mode of A. all the problems change to the possibility of finding the combination mode of A. go to the code.

#include <iostream>
using namespace std;
long long n,s,a,b;
int f[100];//Its subscript is the number of A. assuming a=7, f[7] represents how many possibilities can be formed when the number of a is 7. It can be 4 + 3 or 4 + 2 + 1, just like the two cases described above.

//When talking about the implementation of this function below, some students may not understand it. It is very similar to the idea of 01 knapsack problem, which uses the idea of sliding array. You can see my explanation of 01 knapsack problem above. If you master it, I believe it will be helpful to your programming ability.

//The following dynamic programming is realized by directly transforming the two-dimensional idea into one-dimensional. If you don't understand it, you can see my explanation of 01 knapsack problem.
//Let's simulate and explain it in a two-dimensional way. Let's use a two-dimensional array f[i][j]. In the following way, we directly convert the two-dimensional array f [] [] into a one-dimensional array f [].
//Before we start, in case we confuse the two-dimensional array f [] [] It has nothing to do with finding the number of A. after finding the number of a, use this array to analyze the combination methods of the number of A. for example, when the number of a is 7, how many possibilities can be used to form this number. It can be 4 + 3 or 4 + 2 + 1.
//OK, then formally explain the meaning of I and j in f[i][j]. I represents the possible number of current A. remember that only a has nothing to do with b (it can be 1, 2, 3, 4...), it starts from 1, and j represents the sum of the values of the first I.
//First of all, the value of f[i][0] must be set to 1. This is very detailed, and I will understand it with a few examples below.
//   f[i][j]=f[i-1][j], when J < I.
//	f[i][j]=f[i-1][j]+f[i-1][j-i], when J > = 2.
//Let me explain in detail the real meaning of I, such as f[3][2], which means that any array selected from the numbers 1, 2 and 3 can form the final sum (j). Here, the corresponding sum (j) is 2 and can form 2. Only one case is to directly select 2, and all f[3][2] = 1 (please note that J < I in f[3][2], and the formula used is f[i][j]=f[i-1][j] For example, f[4][2] means to select any number from the four numbers 1, 2, 3 and 4 to get 2. There is only one possibility, that is, to directly select 2, so f[4][2]=1. (at this time, please note that j < I in f[4][2], the formula used is f[i][j]=f[i-1][j]. And f[3][3], the substitution table means to select any number from the three numbers 1, 2 and 3 to form sum (j), which corresponds to sum (j) There are two ways to form 3. Choose 1 and 2, or choose 3 directly, so f[3][3]=2. (at this time, please note that J > = I in f[3][3], so the formula used is f[i][j]=f[i-1][j]+f[i-1][j-i]). We bring in the specific number, that is, f[3][3]=f[2][3]+f[2][0]. Please note whether f[3][0] appears here, that is, f[i][0] This is why f[i][0] should be set to 1. At this time, j=i, so f[2][0] appears. Let's deeply analyze the meaning of f[3][3]=f[2][3]+f[2][0]. The left part f[3][3] needs to be superimposed on the right part (that is, the last state). The expression f[2][3] It means to find a situation in which 3 can be combined from the two numbers 1 and 2, that is, 1 + 2, that is, both numbers 1 and 2 should be selected. And the part f[2][0] means that at this time, f[3][3] has been selected on the left, from the original number 1 and 2 to the current number 1, 2 and 3, and 3 has been selected (key understanding), so the function of f[2][0] is to judge, after 3 has been selected (key understanding), and then select the case satisfying 0 from the two numbers 1 and 2, which also explains why all f[i][0] should be set to 1. Well, I can only talk about this. As for how to convert two-dimensional f[i][j] into one-dimensional f[i] Please refer to the 01 knapsack problem I mentioned. It is strongly recommended that you understand these two problems, which is very helpful for you to understand dynamic programming!!
void dp(int x)		
{
    f[0]=1;
    for(int i=1;i<x;i++)	//Briefly explain why I < x is not I < = X. please look at the table below. a began to appear from No. 2. Please understand it yourself.

//|Serial number | corresponding value|
//| :--: | :-------- |
//|  1   | x         |
//|  2   | x+a       |
//|  3   | x+a+a     |
//|  4   | x+a+a-b   |
//|  5   | x+a+a-b-b |
//|Sum | 5x+7a-3b|
    {
        for(int j=i*(1+i)/2;j>=i;j--)
        {
            f[j]=f[j]+f[j-i];
        }
    }
}

Full code:

#include <iostream>
using namespace std;
long long n,s,a,b;
int f[100];
void dp(int x)		
{
    f[0]=1;
    for(int i=1;i<x;i++)
    {
        for(int j=i*(1+i)/2;j>=i;j--)
        {
            f[j]=f[j]+f[j-i];
        }
    }
}
int main()
{
   cin>>n>>s>>a>>b;
    dp[n];
    int ans=0;
    int num=n*(n-1)/2;
    for(int i=0;i<=num;i++)
    {
        long long h=s-i*a+(num-i)*b;
        if(h%n==0)
            ans+=f[i];
    }
    cout<<ans;
    system("pause");
    return 0;
}

Topics: C C++ data structure