石子合并问题

本文探讨了在一个圆形操场上的石子合并问题,通过编程计算将多堆石子合并成一堆所需的最小和最大得分。利用动态规划算法进行优化,提供了一个有效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

石子合并问题

Time Limit:1000MS  Memory Limit:65536K
Total Submit:135 Accepted:54

Description

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

Input

输入包括多组测试数据,每组测试数据包括两行。

第1 行是正整数n,1<=n<=100,表示有n堆石子。
第2行有n个数,分别表示每堆石子的个数。

Output

对于每组输入数据,输出两行。

第1 行中的数是最小得分;第2 行中的数是最大得分。

Sample Input

4
4 4 5 9

Sample Output

43
54

Source

elba


  •   var
         n,i,j,k,ans:longint;  
         a:array[1..200] of longint;  
         b,f:array[1..200,1..200] of longint;  
        function min(a,b:longint):longint;  
        begin  
               if a<b then exit(a)  
                      else exit(b);  
        end;  
    
        function max(a,b:longint):longint;  
    
        begin  
    
                if a>b then exit(a)  
    
                       else exit(b);  
    
        end;  
    
        begin  
    
                readln(n);  
    
                for i:=1 to n do read(a[i]);  
    
                for i:=1 to n do a[i+n]:=a[i];  
    
                for i:=1 to n*2 do  
    
                    for j:=1 to n*2 do  
    
                        for k:=i to j do b[i,j]:=b[i,j]+a[k];  
    
                fillchar(f,sizeof(f),63);  
    
                for i:=1 to 2*n do f[i,i]:=0;  
    
                for i:=2 to n do  
    
                    for j:=1 to n*2-i+1 do  
    
                        for k:=j+1 to j+i-1 do  
    
                        f[j,j+i-1]:=min(f[j,j+i-1],f[j,k-1]+f[k,j+i-1]+b[j,j+i-1]);  
    
                ans:=maxlongint;  
    
                for i:=1 to n do ans:=min(ans,f[i,i+n-1]);  
    
                writeln(ans);  
    
                fillchar(f,sizeof(f),0);  
    
                for i:=2 to n do  
    
                    for j:=1 to n*2-i+1 do  
    
                        for k:=j+1 to j+i-1 do  
    
                        f[j,j+i-1]:=max(f[j,j+i-1],f[j,k-1]+f[k,j+i-1]+b[j,j+i-1]);  
    
                ans:=0;  
    
                for i:=1 to n do ans:=max(ans,f[i,i+n-1]);  
    
                writeln(ans);  
    
        end.  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值