• 算法


    题目分析

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

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

    解题方法                                                                   

    石子堆合并的最后一次记分为:数组仅剩两个元素,最后一次记分为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();
    
    }
    
     
  • 相关阅读:
    Alpha 冲刺报告6
    课堂小测(同学录)
    Alpha 冲刺报告5
    alphe4
    Alpha 冲刺报告3
    软件工程实践2017第二次作业
    软件工程实践2017第一次作业
    面向对象程序设计 第六次作业
    1025 反转链表(待完善)
    面向对象程序设计 第五次作业
  • 原文地址:https://www.cnblogs.com/liutianchen/p/8506098.html
Copyright © 2020-2023  润新知