算法

题目分析

将石子堆排成一圈后,每次合并相邻的两堆石子,记得分为一次合并堆的石子,求最大得分和最小的分

由于圆形排列的石子堆可以视为首尾元素可合并的直线排列,所以直接分析直线石子堆

解题方法                                                                   

石子堆合并的最后一次记分为:数组仅剩两个元素,最后一次记分为0号与1号元素相加

石子堆合并的过程中,要想保证最后的得分最小,则需要保证每次合并的两堆石子之和是最小的。 因此:

设置当前数组为stone

两两相邻的合并结果为nstone

找到最小的合并结果后,将其他元素替换为剩余的元素,将数组大小-1

全局变量的值加上每次合并后被保留的结果

Stone:

4

4

5

9

Nstone:

8

9

14

13

8

5

9

完成递归后,可得到最小记分,最大记分同理

运行结果

代码

#include <iostream>

#include <cmath>

#include <algorithm>

#include <cstdlib>

 

using namespace std;

 

int n;

int r = 0;

 

void minsum(int *stone, int size) {

 

    if (size == 2) {

        r+=(stone[0] + stone[1]);

    }

    else {

        int nstone[100];

        int min = 0, mi = 0;

        for (int i = 0; i < size - 1; i++) {

            nstone[i] = stone[i] + stone[i + 1];

            if (nstone[i] <= min) {

                min = nstone[i];

                mi = i;

            }

        }

 

        for (int i = 0, j = 0; i < size-1; i++,j++) {

            if (i > mi) {

                nstone[i] = stone[i + 1];

            }

            else if (i < mi) {

                nstone[i] = stone[i];

            }

            else {

                r += nstone[i];

            }

        }

 

        minsum(nstone, size - 1);

    }

}

 

void maxsum(int *stone, int size) {

 

    if (size == 2) {

        r += (stone[0] + stone[1]);

    }

    else {

        int nstone[100];

        int max = 0, mi = 0;

        for (int i = 0; i < size - 1; i++) {

            nstone[i] = stone[i] + stone[i + 1];

            if (nstone[i] > max) {

                max = nstone[i];

                mi = i;

            }

        }

 

        for (int i = 0, j = 0; i < size - 1; i++, j++) {

            if (i > mi) {

                nstone[i] = stone[i + 1];

            }

            else if (i < mi) {

                nstone[i] = stone[i];

            }

            else {

                r += nstone[i];

            }

        }

 

        maxsum(nstone, size - 1);

    }

}

 

 

int main() {

 

 

    cin >> n;

 

    int stone[100];

    for (int i = 0; i < n; i++) {

        cin >> stone[i];

    }

 

    r = 0;

    minsum(stone, n);

    cout << r << endl;

 

    r = 0;

    maxsum(stone, n);

    cout << r << endl;

    getchar();

}

 
原文地址:https://www.cnblogs.com/liutianchen/p/8506098.html