Study Notes of "Programs and Algorithms (2) Algorithm Basis" by Professor Guo Wei of Peking University

Learn programs and algorithms, and you will not be afraid to travel all over the world!

——Guo Wei

Chapter 1 Enumeration

  • Enumeration is a problem-solving strategy based on trying answers one by one.

Example 1 perfect cube

Question: An equation of the form a3 = b3 + c3 + d3 is called a perfect cubic equation. For example 123= 63 + 83 + 103. Write a program to find all quadruples (a, b, c, d) for any given positive integer N (N≤100), such that a3 = b3 + c3 + d3, where a, b, c, d Greater than 1, less than or equal to N, and b<=c<=d.

I write:

#include <iostream>
#include <cmath>

using namespace std;

bool test(int a,int b,int c,int d);

int main()
{
    
    
    cout << "please enter number N" << endl;
    int N;
    cin >> N;
    
    int a, b, c, d;
    for(a=1;a<=N;a++)
    {
    
    
        for(b=1;b<=N;b++)
        {
    
    
            for(c=b;c<=N;c++)
            {
    
    
                for(d=c;d<=N;d++)
                {
    
    
                    if(test(a,b,c,d))
                    {
    
    
                        printf("Cube = %d, Triple = (%d,%d,%d)\n", a,b,c,d);
                    }
                    else
                    {
    
    
                        continue;
                    }
                }
            }
        }
    }
}

bool test(int a,int b,int c,int d)
{
    
    
    if(pow(a,3) == pow(b,3)+pow(c,3)+pow(d,3))
    {
    
    
        return 1;
    }
    else
    {
    
    
        return 0;
    }
}

mark answer:

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
    
    
    int N;
    scanf("%d", &N);
    for (int a = 2; a <= N; ++a)
        for (int b = 2; b < a; ++b)
            for (int c = b; c < a; ++c)
                for (int d = c; d < a; ++d)
                    if (a * a * a == b * b * b + c * c * c + d * d * d)
                        printf("Cube = %d, Triple = (%d,%d,%d)\n", a, b, c, d);

    return 0;
}

It turns out that there is no need to put so many curly braces,
but I don’t understand why abc is smaller than a. In
some places, it is slightly more convenient to output in C language style.
In VScode, you can right-click to format the code

Example 2 Menstrual cycle

Topic: People have the peak days of physical strength, emotional intelligence, and IQ, which occur every 23 days, 28 days, and 33 days respectively. For each, we want to know when the three peaks fall on the same day. Given the days p, e and i (not necessarily the day when the first peak appears) of the three peaks, and another specified day d, your task is to output the next three peaks after day d Days falling on the same day (expressed in days from distance d). For example: the given day is 10, and the next day when three peaks appear on the same day is 12, then output 2.

I write:

#include <iostream>

using namespace std;

bool test(int t, int j, int ini);

int main()
{
    
    
    cout << "please enter p e i and d " << endl;
    int p, e, i, d;
    cin >> p >> e >> i >> d;

    int j;
    for(j=d+1;;j++)
    {
    
    
        if(test(23,j,p) && test(28,j,e) && test(33,j,i))
        {
    
    
            cout << "The next triple peak occurs in " << j-d << " days" << endl;
            break;
        }
        else
        {
    
    
            continue;
        }
    }
}

bool test(int t, int j, int ini)
{
    
    
    if((j-ini)%t == 0)
        return 1;
    else
        return 0;
}

mark answer:

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
    
    

    int p, e, i, d;
    while (cin >> p >> e >> i >> d && p != -1)
    {
    
    
        int k;
        for (k = d + 1; (k - p) % 23; ++k)
            ;
        for (; (k - e) % 28; k += 23)
            ;
        for (; (k - i) % 33; k += 23 * 28)
            ;
        cout << "the next triple peak occurs in " << k - d << " days." << endl;
    }
    return 0;
}

Example Three Weighing Coins

Question: There are 12 coins. Among them were 11 genuine coins and 1 counterfeit coin. Counterfeit and real coins weigh differently, but it is not known whether the counterfeit is lighter or heavier than the real one. Now, use a balance to weigh these coins three times, tell you the weighing results, please find out the counterfeit coins and determine whether the counterfeit coins are light or heavy (the data guarantee can be found)

mark answer:

#include <iostream>
#include <cstring>

using namespace std;

char Left[3][7];    //coins on the left, 3 results in total, one string can contain 7 chars
char Right[3][7];
char result[3][7];

bool IsFake(char c, bool light); //define a function, to test a coin is whether light or heavy

int main()
{
    
    
    int t; //number of groups
    cin >> t;
    while(t--)
    {
    
    
        for(int i = 0; i < 3; i++) cin >> Left[i] >> Right[i] >> result[i]; //read three situatiionss in one group
        for(char c = 'A'; c <= 'L'; c++)
        {
    
    
            if( IsFake(c, true) )
            {
    
    
                cout << c << " is the counterfeit coin and it is light.\n";
                break;
            }
            else if( IsFake(c, false) )
            {
    
    
                cout << c << " is the counterfeit coin and it is heavy.\n";
                break;
            }
        }
    }
    return 0;
}

bool IsFake(char c, bool light) 
{
    
    
    for(int i = 0; i < 3; i++) //for the three situations in one group
    {
    
    
        char *pLeft, *pRight;
        if(light)
        {
    
    
            pLeft = Left[i];
            pRight = Right[i];
        }
        else                  //if the fake coin is heavy, we swap the left and right
        {
    
    
            pLeft = Right[i];
            pRight = Left[i];
        }
        switch(result[i][0]) //use the first letter of up even down to switch between cases
        {
    
    
            case 'u':
                if(strchr(pRight,c) == NULL) //check if char c is in the string at which pRight points
                    return false;
                break;
            case 'e':
                if(strchr(pLeft,c) || strchr(pRight,c))
                    return false;
                break;
            case 'd':
                if(strchr(pLeft,c) == NULL)
                    return false;
                break;    
        }
    }
    return true;
}

Remember these writing methods
while(t–)
for(int i = 0; i < 3; i++)
for(char c = 'A'; c <= 'L'; c++)
case 'u':

chatGPT, using enumeration and structure:

#include <iostream>
#include <cstring>

using namespace std;

enum Result {
    
    UP, EVEN, DOWN};

struct Group {
    
    
    char Left[7];
    char Right[7];
    Result result;
};

bool IsFake(char c, bool light, Group g[3]);

int main()
{
    
    
    int t;
    cin >> t;
    while(t--)
    {
    
    
        Group g[3];
        for(int i = 0; i < 3; i++)
        {
    
    
            cin >> g[i].Left >> g[i].Right;
            string res;
            cin >> res;
            if(res == "up") g[i].result = UP;
            else if(res == "even") g[i].result = EVEN;
            else g[i].result = DOWN;
        }
        for(char c = 'A'; c <= 'L'; c++)
        {
    
    
            if(IsFake(c, true, g))
            {
    
    
                cout << c << " is the counterfeit coin and it is light.\n";
                break;
            }
            else if(IsFake(c, false, g))
            {
    
    
                cout << c << " is the counterfeit coin and it is heavy.\n";
                break;
            }
        }
    }
    return 0;
}

bool IsFake(char c, bool light, Group g[3])
{
    
    
    for(int i = 0; i < 3; i++)
    {
    
    
        char *pLeft, *pRight;
        if(light)
        {
    
    
            pLeft = g[i].Left;
            pRight = g[i].Right;
        }
        else
        {
    
    
            pLeft = g[i].Right;
            pRight = g[i].Left;
        }
        switch(g[i].result)
        {
    
    
            case UP:
                if(strchr(pRight,c) == NULL)
                    return false;
                break;
            case EVEN:
                if(strchr(pLeft,c) || strchr(pRight,c))
                    return false;
                break;
            case DOWN:
                if(strchr(pLeft,c) == NULL)
                    return false;
                break;
        }
    }
    return true;
}

Example 4 Turn off the lights

Post a bit operation error code:

int main()
{
    
    
    int i = 1;
    i << 3; 
    cout << i;
}

The value of the variable i has not been changed here
and should be modified to:

int main()
{
    
    
    int i;
    i = 1;
    i = i << 3;
    cout << i;
}


Assign 1 to i the value after bit operation

#include <memory>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;
int GetBit(char c, int i)
{
    
    
    // 取c的第i位
    return (c >> i) & 1;
}
void SetBit(char &c, int i, int v)
{
    
    
    // 设置c的第i位为v
    if (v)
        c |= (1 << i);
    else
        c &= ~(1 << i);
}
void Flip(char &c, int i)
{
    
    
    // 将c的第i位为取反
    c ^= (1 << i);
}
void OutputResult(int t, char result[]) // 输出结果
{
    
    
    cout << "PUZZLE #" << t << endl;
    for (int i = 0; i < 5; ++i)
    {
    
    
        for (int j = 0; j < 6; ++j)
        {
    
    
            cout << GetBit(result[i], j);
            if (j < 5)
                cout << " ";
        }
        cout << endl;
    }
}
int main()
{
    
    
    char oriLights[5]; // 最初灯矩阵,一个比特表示一盏灯
    char lights[5];    // 不停变化的灯矩阵
    char result[5];    // 结果开关矩阵
    char switchs;      // 某一行的开关状态
    int T;
    cin >> T;
    for (int t = 1; t <= T; ++t)
    {
    
    
        memset(oriLights, 0, sizeof(oriLights));
        for (int i = 0; i < 5; i++)
        {
    
     // 读入最初灯状态
            for (int j = 0; j < 6; j++)
            {
    
    
                int s;
                cin >> s;
                SetBit(oriLights[i], j, s);
            }
        }
        for (int n = 0; n < 64; ++n)
        {
    
     // 遍历首行开关的64种状态
            memcpy(lights, oriLights, sizeof(oriLights));
            switchs = n; // 第i行的开关状态
            for (int i = 0; i < 5; ++i)
            {
    
    
                result[i] = switchs; // 第i行的开关方案
                for (int j = 0; j < 6; ++j)
                {
    
    
                    if (GetBit(switchs, j))
                    {
    
    
                        if (j > 0)
                            Flip(lights[i], j - 1); // 改左灯
                        Flip(lights[i], j);         // 改开关位置的灯
                        if (j < 5)
                            Flip(lights[i], j + 1); // 改右灯
                    }
                }
                if (i < 4)
                    lights[i + 1] ^= switchs; // 改下一行的灯
                switchs = lights[i];          // 第i+1行开关方案和第i行灯情况同
            }
            if (lights[4] == 0)
            {
    
    
                OutputResult(t, result);
                break;
            }
        } // for( int n = 0; n < 64; n ++ )
    }
    return 0;
}

Chapter 2 Recursion (1)

Example 1 Finding the factorial

#include <iostream>

int get_factorial(int n)
{
    
    
	int factorial;
	
	if(n == 0)
	{
    
    
		factorial = 1;
	}
	else
	{
    
    
		factorial = n * get_factorial(n-1);
	}
	return factorial;
}

int main()
{
    
    
	int n;
	
	std::cin >> n;
	
	std::cout << get_factorial(n); 
}

Example 2 Tower of Hanoi

I write:

#include <iostream>

using namespace std;

void move_method(int n, char start, char transit, char destination)
{
    
    
    if (n == 2)
    {
    
    
        cout << start << "->" << transit << endl;
        cout << start << "->" << destination << endl;
        cout << transit << "->" << destination << endl;
    }
    else if (n > 2)
    {
    
    
        move_method(n - 1, start, destination, transit);
        cout << start << "->" << destination << endl;
        move_method(n - 1, transit, start, destination);
    }
}

int main()
{
    
    
    int n;
    cin >> n;
    move_method(n, 'A', 'B', 'C');
}

Example three n queens problem

mark answer:

#include <iostream>
#include <cmath>

using namespace std;

void nQueens(int k);

int queenPosition[100]; // queen's position fron line0 to line(n-1), assume n <= 100
int N;

int main()
{
    
    
    cin >> N;
    nQueens(0); // start from line0
}

void nQueens(int k) // put a queen in linek
{
    
    
    if (k == N) // if N queens (line0 to line N-1) are well positioned
    {
    
    
        for (int i = 0; i < N; i++) // for every line
        {
    
    
            cout << queenPosition[i] + 1 << " "; // print the results
        }
        cout << endl;
    }

    // below is the actually working function
    for (int i = 0; i < N; i++) // for every position in linek
    {
    
    
        int j = 0;
        for (j = 0; j < k; j++) // for all the positioned queens
        {
    
    
            if (queenPosition[j] == i || abs(queenPosition[j] - i) == abs(k - j)) // if conlicting
            {
    
    
                break; // stop trying, jump out the inner loop and try the next position in linek
            }
        }
        if (j == k)
        {
    
    
            queenPosition[k] = i;
            nQueens(k + 1); // to deal with next line
        }
    }
}

Example Four Inverse Polish Expressions

mark answer:

#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;

double exp()
{
    
    
    // 读入一个逆波兰表达式,并计算其值
    char s[20];
    cin >> s;
    switch (s[0])
    {
    
    
    case '+':
        return exp() + exp();
    case '-':
        return exp() - exp();
    case '*':
        return exp() * exp();
    case '/':
        return exp() / exp();
    default:
        return atof(s);
        break;
    }
}
int main()
{
    
    
    printf("%lf", exp());
    return 0;
}

Supplementary Notes (from theCherno)

  • Both break and continue are for the loop,
    one is to jump out of this loop, and the other is to enter the next round of loop
  • The things inside for can be very flexible. The initialization of the loop variable, the start condition of a new round of loop, and the adjustment of the loop variable at the end of each loop, just fill in them separately.

Chapter 3 Recursion (2)

Example 1 Find the value of an expression

my answer:

#include <iostream>

using namespace std;

int expression_value();
int term_value();
int factor_value();

int main()
{
    
    
    cout << expression_value() << endl;
    return 0;
}

int expression_value()
{
    
    
    int result = 0;
    result = term_value(); // the value of first term
    char operation = cin.peek();
    while (operation == '+' || operation == '-')
    {
    
    
        cin.get();
        if (operation == '+')
        {
    
    
            result += term_value();
        }
        else if (operation == '-')
        {
    
    
            result -= term_value();
        }
        else
            break;
        operation = cin.peek();
    }
    return result;
}

int term_value()
{
    
    
    int result = 1;
    result = factor_value(); // the value of first term
    char operation = cin.peek();
    while (operation == '*' || operation == '/')
    {
    
    
        cin.get();
        if (operation == '*')
        {
    
    
            result *= factor_value();
        }
        else if (operation == '/')
        {
    
    
            result /= factor_value();
        }
        else
            break;
        operation = cin.peek();
    }
    return result;
}

int factor_value()
{
    
    
    int result = 0;
    char element = cin.peek();
    if (element == '(')
    {
    
    
        cin.get();
        result = expression_value();
        cin.get();
    }
    else
    {
    
    
        int digit;
        cin >> digit;
        result = result * 10 + digit;
    }
    return result;
}

Woooooo chatGPT has helped me a lot, I love it so much,
I remember the magic to hang on the Internet

A word of caution:
cin.get() can take away a character, taking the leftmost character from the input stream.
cin.peek() can read the leftmost character without taking it away
insert image description here

Example 2 Climb the stairs

my answer:

#include <iostream>

using namespace std;

int get_combinatioins(int N);

int main()
{
    
    
    cout << "please enter the number of steps" << endl;
    int N = cin.get();
    get_combinatioins(N);
    return 0;
}

int get_combinatioins(int N)
{
    
    
    int combinations;
    if (N == 1)
        combinations = 1;
    else if (N == 2)
        combinations = 2;
    else if (N > 2)
        combinations = get_combinatioins(N - 1) + get_combinatioins(N - 2);
    return combinations;
}

Example Three Calculation 24

fabs is to find the absolute value of floating-point numbers, and abs is to find the absolute value of integers.
The function prototype (remember this term) is int abs (int x) and float fabs (float x)

Press F11 to switch between full screen and non-full screen mode

Scribe mark answer woo woo:

#include "iostream"
#include "cmath"

using namespace std;

double a[5];
#define EPS 1e-6

bool isZero(double x)
{
    
    
    return fabs(x) <= EPS;
}

bool count24(double a[], int n)
{
    
    
    if (n == 1)
    {
    
    
        if (isZero(a[0] - 24))
            return true;
        else
            return false;
    }

    double b[5];

    for (int i = 0; i < n - 1; i++)
    {
    
    
        for (int j = i+1; j < n; j++) // double loops to enumerate combinations of two numbers
        {
    
    
            int m = 0;
            for (int k = 0; k < n; k++)
            {
    
    
                if (k != i && k != j)
                    b[m++] = a[k];
            }
            b[m] = a[i] + a[j];
            if (count24(b, m + 1))
                return true;
            b[m] = a[i] - a[j];
            if (count24(b, m + 1))
                return true;
            b[m] = a[j] - a[i];
            if (count24(b, m + 1))
                return true;
            b[m] = a[i] * a[j];
            if (count24(b, m + 1))
                return true;
            if (!isZero(a[j]))
            {
    
    
                b[m] = a[i] / a[j];
                if (count24(b, m + 1))
                    return true;
            }
            if (!isZero(a[i]))
            {
    
    
                b[m] = a[j] / a[i];
                if (count24(b, m + 1))
                    return true;
            }
        }
    }
    return false;
}

int main()
{
    
    
    while (true)
    {
    
    
        for (int i = 0; i < 4; i++)
            cin >> a[i];
        if (isZero(a[0]))
            break;
        if (count24(a, 4))
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

notes:

  • If you want to compare two code files in vscode, you can ctrl select the two files to be compared in the left project column, right click and select compare selected
  • Judging the equality of integers directly ==, and judging the equality of floating-point numbers, we have to use the difference less than the machine precision. In the code, you can define an esp macro, that is, the machine epsilon is 1e-6, here ϵ \epsilonϵ is a bit like Shufen's thinking haha. Then define a function isZero that judges whether it tends to zero. Just call this function when you need to judge.
  • You want to perform an operation in a loop, but judging the loop condition is more complicated. If you don’t want to put it in the brackets after while, you can do while(true), then break; in the termination condition and go out.

Chapter 4 Bisection Algorithm

The binary algorithm requires an ordered sequence
that can be sorted using sort, and the time complexity is nlogn

Example 1 Finding the Roots of the Equation

#include <iostream>
#include <cmath>
#include <iomanip>

#define epsilon 1e-6

using namespace std;

double get_solution();

int main()
{
    
    
    cout << fixed << setprecision(8) << get_solution() << endl;
}

double get_solution()
{
    
    
    double left = 0, right = 100;
    double solution = (left + right) / 2;
    double function_value = pow(solution, 3) - 5 * pow(solution, 2) + 10 * solution - 80;
    while (fabs(function_value - 0) > epsilon)
    {
    
    
        if (function_value > 0)
            right = solution;
        else if (function_value < 0)
            left = solution;

        solution = (left + right) / 2;
        function_value = pow(solution, 3) - 5 * pow(solution, 2) + 10 * solution - 80;
    }
    return solution;
}

cout << fixed << setprecision(8) << get_solution() << endl; this sentence is what chaatGPT told me to output. Just remember that there is this way, just search for the specific grammar when the time comes.
Remember to use fabs for the absolute value of floating point numbers, abs is useless.

Example 2 Find a pair of numbers

Find all the currently selected words in the text at once: Ctrl + Shift + L
A small piece of experimental code: Check the way to pass values ​​to the function:

#include <iostream>

using namespace std;

const int MAX_N = 100000;

void get_numbers(int &n, int *arr);

int main()
{
    
    
    int n;
    int arr[MAX_N];
    get_numbers(n, arr);
    for (int i = 0; i < n; i++)
    {
    
    
        cout << arr[i];
    }
}

void get_numbers(int &n, int *arr)
{
    
    
    cin >> n;

    for (int i = 0; i < n; i++)
    {
    
    
        cin >> arr[i];
    }
}

insert image description here
In the function defined by yourself, it doesn't matter if you use n or N or even number. As long as & is added to the parameter list, the value of the actual parameter can be modified. like·:

void get_numbers(int &number, int *arr)
{
    
    
    cout << "enter n:" << endl;
    cin >> number;
    cout << "enter the n numbers:" << endl;
    for (int i = 0; i < n; i++)
    {
    
    
        cin >> arr[i];
    }
}

Also, when defining an array, specify its size

my answer:

#include <iostream>
#include <algorithm>

using namespace std;

const int MAX_N = 100000;

void get_numbers(int &n, int *arr);
void find_the_pair(int *arr, int &n, int &m);

int main()
{
    
    
    cout << "enter m: " << endl;
    int m;
    cin >> m;
    
    int n;
    int arr[MAX_N];
    get_numbers(n, arr);
    sort(arr, arr + n);
    find_the_pair(arr, n, m);
}

void get_numbers(int &n, int *arr)
{
    
    
    cout << "enter n:" << endl;
    cin >> n;
    cout << "enter the n numbers:" << endl;
    for (int i = 0; i < n; i++)
    {
    
    
        cin >> arr[i];
    }
}

void find_the_pair(int *arr, int &n, int &m)
{
    
    
    int i = 0, j = n - 1;
    int small = arr[i];
    int big = arr[j];
    int sum;
    while (true)
    {
    
    
        sum = small + big;
        bool keeptrying = true;
        if (sum < m)
        {
    
    
            i++;
            small = arr[i];
            continue;
        }
        else if (sum > m)
        {
    
    
            j--;
            big = arr[j];
            continue;
        }
        else if (sum == m)
        {
    
    
            cout << small << " " << big << endl;
            break;
        }
    }
}

Example 3 Mad Cow

When there is a lot of input data, scanf will be more efficient.
Shift+letter keys can be typed in uppercase.
The format code can be Ctrl+Shift+I.
The gdb I always see is the GNU symbolic debugger.
Also, the array is directly defined in the main function as Global variables are just fine, every function can be operated, don't refer to them.
Numb, debug failed. don't paste the code

Chapter 5 Partition

merge sort

Complexity nlogn
"copy Song Tie":

#include <iostream>
using namespace std;

int a[10] = {
    
    13, 27, 19, 3, 8, 12, 2, 8, 30, 89};
int b[10]; // to have a storage to store the sorted array

void MergeSort(int a[], int start, int end, int tmp[]);

int main()
{
    
    
    int size = sizeof(a) / sizeof(int);
    MergeSort(a, 0, size - 1, b);
    for (int i = 0; i < size; i++)
    {
    
    
        cout << a[i] << ",";
    }
    cout << endl;
    return 0;
}

void Merge(int a[], int start, int middle, int end, int tmp[])
{
    
    
    int pointerb = 0;
    int pointer1 = start, pointer2 = middle + 1;
    while (pointer1 <= middle && pointer2 <= end)
    {
    
    
        if (a[pointer1] < a[pointer2])
        {
    
    
            tmp[pointerb++] = a[pointer1++];
        }
        else
        {
    
    
            tmp[pointerb++] = a[pointer2++];
        }
    }
    
    while (pointer1 <= middle)
        tmp[pointerb++] = a[pointer1++];
    
    while (pointer2 <= end)
        tmp[pointerb++] = a[pointer2++];
    
    for (int i = 0; i < end - start + 1; ++i)
        a[start + i] = tmp[i];
}

void MergeSort(int a[], int start, int end, int tmp[])
{
    
    
    if (start < end)
    {
    
    
        int middle = start + (end - start) / 2;
        MergeSort(a, start, middle, tmp);
        MergeSort(a, middle + 1, end, tmp);
        Merge(a, start, middle, end, tmp);
    }
}

You can select all variable names and rename this variable. (Shortcut key: select and add F2)
divide and conquer; recursion;

quick sort

#include <iostream>
using namespace std;
int main()
{
    
    
    int a[3] = {
    
    1, 2, 3};
    int i = 0;
    cout << a[i++] << endl;
    cout << i;
}
//output 1 
//1
#include <iostream>
using namespace std;
int main()
{
    
    
    int a[3] = {
    
    1, 2, 3};
    int i = 0;
    cout << a[++i] << endl;
    cout << i;
}
//output 2 
//1
#include <iostream>
using namespace std;
int main()
{
    
    
    int a[3] = {
    
    1, 2, 3};
    int i = 1;
    a[i--] = 6;
    cout << a[0] << " " << a[1] << endl;
    cout << i;
}
//output 1 6
0

// About IDE(clion):
// The IDE I use is clion, chasing stars
// shift + alt + < or > can change the font size
// Changing the input method in the lower right corner to ENG can prevent Chinese and The input of its punctuation
//About the array:

int length = sizeof(a)/sizeof(a[0])
for(int i = 0; i < length; i++)

Chapter 6 Dynamic Programming

number triangle

#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN = 105;

int N;
int triangle[MAXN][MAXN];
int dp[MAXN][MAXN];

int main() {
    
    
    cin >> N;
    for (int i = 1; i <= N; i++) {
    
    
        for (int j = 1; j <= i; j++) {
    
    
            cin >> triangle[i][j];
        }
    }

    // 初始化最后一行的 dp 值
    for (int j = 1; j <= N; j++) {
    
    
        dp[N][j] = triangle[N][j];
    }

    // 自底向上进行动态规划
    for (int i = N-1; i >= 1; i--) {
    
    
        for (int j = 1; j <= i; j++) {
    
    
            dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + triangle[i][j];
        }
    }

    // 最终的答案即为 dp[1][1]
    cout << dp[1][1] << endl;

    return 0;
}

It feels like int n and cin>>n can be placed in one line, because one thing is done.

Guess you like

Origin blog.csdn.net/m0_73293161/article/details/128828514