zoukankan      html  css  js  c++  java
  • 算法

    题目分析

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

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

    解题方法                                                                   

    石子堆合并的最后一次记分为:数组仅剩两个元素,最后一次记分为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();
    
    }
    
     
  • 相关阅读:
    【刷题】BZOJ 1036 [ZJOI2008]树的统计Count
    【刷题】BZOJ 1180 [CROATIAN2009]OTOCI
    【刷题】BZOJ 1453 [Wc]Dface双面棋盘
    【刷题】BZOJ 4025 二分图
    【模考】2018.04.08 Connection
    【模考】2018.04.08 Travel
    【刷题】BZOJ 4825 [Hnoi2017]单旋
    【刷题】洛谷 P3613 睡觉困难综合征
    【刷题】BZOJ 3668 [Noi2014]起床困难综合症
    CSS3_边框 border 详解_一个 div 的阴阳图
  • 原文地址:https://www.cnblogs.com/liutianchen/p/8506098.html
Copyright © 2011-2022 走看看