当前位置: 首页 > article >正文

动态规划 (环形)

在一个圆形操场的四周摆放着n堆石子,现要将石子有次序地合并成一堆。规定每次只能选相邻2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分。

输入格式:

n表示n堆石子,下一行n个数,表示每堆石子的个数。可能有多组测试数据。

输出格式:

分别输出最小得分和最大得分,空格隔开。每组一行。

输入样例:

在这里给出一组输入。例如:

4
4  4  5  9

输出样例:

在这里给出相应的输出。例如:

43 54

 注:连着找最值 不能 直接找最值合并 例1 3 4 2 5

二维数组几乎全部用到了 不是三角形状 行代表起点开始的位置 列代表从起点开始向后的距离

#include <stdio.h>

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int a[n+1],max[n+1][n+1],min[n+1][n+1];
        for (int i=0;i<n+1;i++)//二维数组全部初始化为0
        {
            for (int j=0;j<n+1;j++)
            {
                min[i][j]=0;
                max[i][j]=0;
            }
        }
        for (int i=1;i<n+1;i++)//输入
            scanf("%d",&a[i]);
        
        for (int len=2;len<=n;len++)//分割长度,从2开始到n结束
        {
            for (int begin=1;begin <=n;begin++)//起点
            {
                int end = begin+len-1;        //终点
                if (end>n)                    //大于才取模 因为从1开始 需要分情况 从0开始不需要
                    end=end%n;
                for (int k=1;k<len;k++)        //分割的长度 从1开始 
                {
                    int sum=0,loc=begin;        //记录合并后需要新加的数
                    for (int ii=0;ii<len;ii++) 
                    {
                        sum+=a[loc++];
                        if (loc>n)
                             loc=(loc)%n;
                    }
                    loc=k+begin;
                    if (loc>n)
                        loc=loc%n;
                    //二维数组几乎全部用到了 不是三角形状 行代表起点开始的位置 列代表从起点开始向后的距离
                    if(!min[begin][len] || min[begin][len] > min[begin][k] + min[loc][len-k] + sum )
                        min[begin][len] = min[begin][k] + min[loc][len-k] + sum;
                    if (!max[begin][len] || max[begin][len] < max[begin][k] + max[loc][len-k] + sum )
                        max[begin][len] = max[begin][k] + max[loc][len-k] + sum;
                }
            }
        }
        int Min=99999,Max=0;
        for (int i=1;i<=n;i++)        //列代表从起点开始向后的距离 所以需要遍历所有起点且距离为n的位置
        {
            if (Min > min[i][n])
                Min = min[i][n];
            if (Max < max[i][n])
                Max = max[i][n];
        }
        printf("%d %d\n",Min ,Max);//[1][n]
    }
}


http://www.kler.cn/a/527413.html

相关文章:

  • 第一个3D程序!
  • 【C语言】动态内存管理
  • Elasticsearch Queries
  • 基于Django的Boss直聘IT岗位可视化分析系统的设计与实现
  • 毕业设计--具有车流量检测功能的智能交通灯设计
  • “星门计划对AI未来的意义——以及谁将掌控它”
  • Spring的AOP的JoinPoint和ProceedingJoinPoint
  • 网络编程复习
  • 从0开始,来看看怎么去linux排查Java程序故障
  • Day31-【AI思考】-深度学习方法论全解析——科学提升学习效率的终极指南
  • Synology 群辉NAS安装(7)lsof指令和synogear
  • 半导体SAP管理系统:数字化转型的驱动力
  • ComfyUI使用教程、开发指导、资源下载
  • 微服务配置中心 Apollo解析——Portal 关联 Namespace
  • 什么是麦克斯韦方程
  • 2025年01月31日Github流行趋势
  • 3 Spark SQL
  • 【leetcode】T541 (两点反思)
  • 新一代搜索引擎,是 ES 的15倍?
  • ARM嵌入式学习--第十一天(中断处理 , ADC)
  • 编程大模型之—Qwen2.5-Coder
  • JVM方法区
  • Array,String,Number
  • ZZNUOJ(C/C++)基础练习1021——1030(详解版)
  • 白话DeepSeek-R1论文(二)| DeepSeek-R1:AI “升级打怪”,从“自学成才”到“全面发展”!
  • 数据结构-Stack和栈