C++程序石子合并问题.docx
- 文档编号:11389102
- 上传时间:2023-02-28
- 格式:DOCX
- 页数:10
- 大小:16.70KB
C++程序石子合并问题.docx
《C++程序石子合并问题.docx》由会员分享,可在线阅读,更多相关《C++程序石子合并问题.docx(10页珍藏版)》请在冰豆网上搜索。
C++程序石子合并问题
石子合并
问题描述:
在一个圆形操场的四周摆放着n堆石子。
现要将石子有次序地合并成一堆。
规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。
试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分。
【输入文件】
包含两行,第1行是正整数n(1<=n<=100),表示有n堆石子。
第2行有n个数,分别表示每堆石子的个数。
【输出文件】
输出两行。
第1行中的数是最小得分;第2行中的数是最大得分。
【输入样例】
4
4459
【输出样例】
43
54
设计算法分析:
1)、此题表面上看是用贪心算法比较合适,实则不然,用贪心算法是每次都合并得分最大的或最小的相邻两堆,但不一定保证余下的合并过程能导致最优解,聪明的读者马上会想到一种理想的假设:
如果N-1次合并的全局最优解包含了每一次合并的子问题的最优解,那么经这样的N-1次合并后的得分总和必然是最优的,这就是动态规划的思想。
采用动态规划求解的关键是确定所有石子堆子序列的最佳合并方案。
这些石子堆子序列包括:
{第1堆、第2堆}、{第2堆、第3堆}、……、{第N堆、第1堆};{第1堆、第2堆、第3堆}、{第2堆、第3堆、第4堆}、……、{第N堆、第1堆、第2堆};……{第1堆、……、第N堆}{第2堆、……、第N堆、第1堆}……{第N堆、第1堆、……、第N-1堆}
为了便于运算,我们用〔i,j〕表示一个从第i堆数起,顺时针数j堆时的子序列{第i堆、第i+1堆、……、第(i+j)堆}(注意:
此时的i+j可能已经超出N的范围,为此我们在读入每堆石子的数量时,把石子堆数扩展为2*N-1,有a[i]=a[i+N],没有a[N+N])
它的最佳合并方案包括两个信息:
2该子序列的各堆石子合并成一堆的过程中,各次合并得分的总和;
②形成最佳得分和的子序列1和子序列2。
由于两个子序列是相邻的,因此只需记住子序列1的堆数;
读者可以从以下详细的程序代码中体会到算法的思想:
//StonesMerger.h
#ifndefSTONESMERGER_H
#defineSTONESMERGER_H
classStonesMerger
{
public:
StonesMerger();
~StonesMerger();
voidrun();//运行接口
private:
intnumber;//石子的堆数
inttotalMax;//记录合并成一堆的最大得分
intX;//记录合并成一堆的最大得分的最优合并的起始堆
inttotalMin;//记录合并成一堆的最小得分
intY;//记录合并成一堆的最小得分的最优合并的起始堆
int*a;//存储石子的数量
int**MAX;//记录子序列合并最大得分
int**Smax;//记录子序列合并最大得分的最佳断开位置
int**min;//记录子序列合并最小得分
int**smin;//记录子序列合并最小得分的最佳断开位置
boolinput();//输入接口读取input.txt文件
voidmostValue();//以第i堆开始合并后面的j堆j=0、1、2、......、n-1
voidoutput();//输出显示
voidtraceback(int**s,intn,intm);//对应于Smax[n][m]或smin[n][m]寻找轨迹
};
#endif
//StonesMerger.cpp
#include
#include
#include
#include
#include"StonesMerger.h"
ifstreaminputFile("input.txt",ios:
:
in);
ofstreamoutputFile("output.txt",ios:
:
out);
#defineN100//根据实际问题规模大小设定恰当的初值
StonesMerger:
:
StonesMerger()
{
number=0;
X=0;
Y=0;
totalMax=0;
totalMin=0;
a=newint[2*N];
MAX=newint*[2*N];
Smax=newint*[2*N];
min=newint*[2*N];
smin=newint*[2*N];
for(inti=0;i<2*N;i++)
{
MAX[i]=newint[2*N];
Smax[i]=newint[2*N];
min[i]=newint[2*N];
smin[i]=newint[2*N];
}
}
StonesMerger:
:
~StonesMerger()
{
delete[]a;
for(inti=0;i<2*N;i++)
{
delete[]MAX[i];
delete[]Smax[i];
delete[]min[i];
delete[]smin[i];
}
delete[]MAX;
delete[]Smax;
delete[]min;
delete[]smin;
}
voidStonesMerger:
:
run()//运行接口
{
if(input())
{
mostValue();
output();
}
}
boolStonesMerger:
:
input()
{
if(!
inputFile)
{
cerr<<"input.txtcouldnotbeopened."< exit (1); } if(! outputFile) { cerr<<"output.txtcouldnotbeopened."< exit (1); } inputFile>>number; outputFile<<"石子堆数为:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+程序 石子合并问题 C+ 程序 石子 合并 问题