1.描述:有一个由n个顶点构成的多边形。每个顶点被赋予一个整数值,每条边被赋予一个运算符“+”或“*”。所有边依次用整数从1到n编号。

游戏第1步,将一条边删除。

随后n-1步按以下方式操作:

(1)选择一条边E以及由E连接着的2个顶点V1和V2;

(2)用一个新的顶点取代边E以及由E连接着的2个顶点V1和V2。将由顶点V1和V2的整数值通过边E上的运算得到的结果赋予新顶点。

最后,所有边都被删除,游戏结束。游戏的得分就是所剩顶点上的整数值。

输入:

输入共两行,第一行一个整数n表示顶点个数,第二行共2*n个数,分别为数字和字符。

例如:对于上图中的问题,我们可以这样按输入样例中的例子输入,数学中的“+”号代表加法,小写字母“x”代表乘法。

输出:

一个整数,计算最高得分。

输入样例:

5

10 + -1 x -2 x 3 + -8 x

输出样例:

486

2.问题分析

解决该问题可用动态规划中的最优子结构性质来解。

设所给的多边形的顶点和边的顺时针序列为op[1],v[1],op[2],v[2],op[3],…,op[n],v[n] 其中,op[i]表示第i条边所对应的运算符,v[i]表示第i个顶点上的数值,i=1~n。

在所给的多边形中,从顶点i(1<=i<=n)开始,长度为j(链中有j个顶点)的顺时针链p(i,j)可表示为v[i],op[i+1],…,v[i+j-1]。

设m1是对子链p[i][s]的任意一种合并方式得到的值,而a和b分别是在所有可能的合并中得到的最小值和最大值。m2是p[i+s][j-s]的任意一种合并方式得到的值,而c和d分别是在所有可能的合并中得到的最小值和最大值。依此定义有a≤m1≤b,c≤m2≤d

(1)当op[i+s]=’+’时,显然有a+c≤m≤b+d

(2)当op[i+s]=’*’时,有min{ac,ad,bc,bd}≤m≤max{ac,ad,bc,bd}

换句话说,主链的最大值和最小值可由子链的最大值和最小值得到。例如,当m=ac时,最大主链由它的两条最小主链组成;同理当m=bd时,最大主链由它的两条最大子链组成。无论哪种情形发生,由主链的最优性均可推出子链的最优性。

综上可知多边形游戏问题满足最优子结构的性质。

3.递归求解

由前面的分析可知,为了求链合并的最大值,必须同时求子链合并的最大值和最小值。因此,在整个计算过程中,应同时计算最大值和最小值。

设m[i,j,0]是链p(i,j)合并的最小值,而m[i,j,1]是最大值。若最优合并在op[i+s]处将p(i,j)分为两个长度小于j的子链p(i,i+s)和p(i+s,j-s),且从顶点i开始的长度小于j的子链的最大值和最小值均已经计算处。为了叙述方便,记

a=m[i,i+s,0]

b=m[i,i+s,1]

c=m[i+s,j-s,0]

d=m[i+s,j-s,1]

(1)当op[i+s]='+'时,

m[i,j,0]=a+c

m[i,j,1]=b+d

(2)当op[i+s]='*'是,

m[i,j,0]=min{ac,ad,bc,bd}

m[i,j,1]=max{ac,ad,bc,bd}

综合(1)和(2),将p(i,j)在op[i+s]处断开的最大值记为maxf(i,j,s),最小值记为minf(i,j,s),则

a+c op[i+s]='+'

minf(i,j,s)={

min{ac,ad,bc,bd} op[i+s]='*'

b+d op[i+s]='+'

maxf(i,j,s)={

max{ac,ad,bc,bd} op[i+s]='*'

由于多边最优断开位置s有1≤s≤j-1的j-1种情况,由此可知

m[i,j,0]=min{minf(i,j,s)} 1≤i,j≤n

m[i,j,1]=max{maxf(i,j,s)} 1≤i,j≤n

初始边界显然为

m[i,j,0]=v[i] 1≤i≤n

m[i,j,1]=v[i] 1≤ i≤n

由于多边形是封闭的,在上面的计算中,当i+s>n是,顶点i+s实际编号为(i+s)mod n。按上述递推式计算出的m[i,n,1]即为首次删去第i条边后得到的最大得分。

4.算法描述

基于以上讨论可设计解多边形游戏问题的动态规划算法如下:

void minMax(int i,int s,int j)

{ int e[5];

int a=m[i][s][0],

b=m[i][s][1],

r=(i+s-1)%n+1,//妙!

c=m[r][j-s][0],

d=m[r][j-s][1];

if(op[r]=='t')

{minf=a+c;

maxf=b+d;

}

else

{

e[1]=a*c;

e[2]=a*d;

e[3]=b*c;

e[4]=b*d;

minf=e[1];

maxf=e[1];

for(int k=2;k<5 kh>

{if(minf>e[k]) minf=e[k];

if(maxf

}

}

}

int polyMax(){

for(int j=2;j<=n;j++)

for(int i=1;i<=n;i++)

for(int s=1;s

{minMax(i,s,j);

m[i][j][0]=100000;

m[i][j][1]=-100000;

if(m[i][j][0]>minf) m[i][j][0]=minf;

if(m[i][j][1]

}

long int temp=m[1][n][1];

for(int i=2;i<=n;i++)

if(temp

return temp;

}

【新方法】

本题在处理顺时针循环时的下标时,有一个很妙的方法。即,

r=(i+s-1)%n+1

其实,本题从这样编纯属巧合。

当i+s 并不需要减一的时候,用这种方法编就很方便。

如果用传统的方法就是

if(i==n) r=n;

else r=i%n

这样,以来r=(i+s-1)%n+1就简单了不少。

【参考程序】

#include

#include

long int minf,maxf,m[51][51][2];

char op[52];

int v[51],n;

void in()

{

FILE *in=fopen("polygon2.in","r");

fscanf(in,"%d",&n);

fgetc(in);

for(int i=1;i<=n;i++)

fscanf(in,"%c %d ",&op[i],&v[i]);

fclose(in);

}

void iniM()

{

for(int i=1;i<=n;i++)

{m[i][1][0]=v[i];

m[i][1][1]=v[i];

}

}

void minMax(int i,int s,int j)

{

int e[5];

int a=m[i][s][0],

b=m[i][s][1],

r=(i+s-1)%n+1,//妙!

c=m[r][j-s][0],

d=m[r][j-s][1];

if(op[r]=='t')

{minf=a+c;

maxf=b+d;

}

else

{

e[1]=a*c;

e[2]=a*d;

e[3]=b*c;

e[4]=b*d;

minf=e[1];

maxf=e[1];

for(int k=2;k<5 kh>

{if(minf>e[k]) minf=e[k];

if(maxf

}

}

}

int polyMax()

{

for(int j=2;j<=n;j++)

for(int i=1;i<=n;i++)

for(int s=1;s

{minMax(i,s,j);

m[i][j][0]=100000;

m[i][j][1]=-100000;

if(m[i][j][0]>minf) m[i][j][0]=minf;

if(m[i][j][1]

}

long int temp=m[1][n][1];

for(int i=2;i<=n;i++)

if(temp

return temp;

}

int main()

{

in();

iniM();

long int max=polyMax();

printf("%ld\n",max);

system("pause");

return 0;

}

动态规划多边形游戏c语言,动态规划-多边形游戏问题相关推荐

  1. C语言数组制作拼图游戏,C语言自制拼图游戏.doc

    C语言自制拼图游戏 C语言~~自制-拼图游戏 原帖及讨论:/thread-233257-1-1.html //编译环境VC++6.0. 程序和资源一共15M. 来自 //需要的留个EMAIL.... ...

  2. c语言案例游戏,C语言实现五子棋游戏的案例

    C语言实现五子棋游戏的案例 发布时间:2020-08-25 09:35:55 来源:亿速云 阅读:120 作者:小新 小编给大家分享一下C语言实现五子棋游戏的案例,相信大部分人都还不怎么了解,因此分享 ...

  3. c语言经典游戏,C语言——经典小游戏——打砖块

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 C语言--经典小游戏--打砖块 玩法:按A与D控制球拍的移动,按S暂停游戏 百度网盘下载:http://pan.baidu.com/s/1o64ECTc ...

  4. c语言设计生命游戏,C语言实现生命游戏.doc

    C语言实现生命游戏 本世纪70年代,人们曾疯魔一种被称作"生命游戏"的小游戏,这种游戏相当简单.假设有一个像棋盘一样的方格网,每个方格中放置一个生命细胞,生命细胞只有两种状态:&q ...

  5. 可乐瓶游戏c语言,小班体育游戏《玩可乐瓶》教案

    小班体育游戏<玩可乐瓶>教案 目标: 1.在老师的引导下,探索可乐瓶的'玩法,发展幼儿的动作. 2.乐意在自然环境中进行锻炼,并知道爱护环境. 过程: 一.激发兴趣,活动身体天亮了,起床了 ...

  6. java三子棋人机游戏_C语言编程入门游戏《三子棋》

    经过C语言初级阶段的系统学习,对基本C语言的知识有了一定的了解和认识,能够通过C语言编程解决一些简单的问题.本次完成一个简单的游戏<三子棋>. 游戏简介:常见的3x3棋盘,有两名游戏玩家, ...

  7. 与猜数问题有关的游戏C语言,猜数字游戏(C语言版)

    最近在研究算法的问题 貌似这是工作中的一个短板 当然 这跟我从事的工作有关 一般不容易接触太多算法问题 .很多时候接触都是一些CRUD  ! 今天空闲了会 写了一个猜数字的游戏  原理很简单 直接上代 ...

  8. 数字炸弹游戏c语言,数字炸弹游戏作文500字

    今天,我们玩了一个超好玩的游子,叫"数字炸弹". 游戏规则:出题的人从1-100选一个数字,假如出题的人写82,其他7人中的一人选了82,那个人喝一杯满满的水,如果没人选82,那出 ...

  9. 猜数字游戏c语言编程,【游戏编程】猜数字游戏(C语言)

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 //此游戏规则为:系统随机生成一个整数,然后要你去猜它.系统会提示你是大了还是小了.游戏结束后会生成排行榜,有记录时间 #include #include ...

最新文章

  1. 给定链表中间某结点指针,删除链表中该结点
  2. python 如何将虚拟环境的项目的所有.py文件的import导包汇总到requirements.txt文件 (pipreqs)
  3. java 容器、二叉树操作、107
  4. JavaScript:事件对象Event和冒泡
  5. SSM项目中整合WebService
  6. Visual C++ 编译器选项 /MD、/ML、/MT、/LD
  7. 数据库一对一,一对多,多对多关系
  8. 虚拟机中安装linux
  9. 全网最新Spring Boot2.5.1整合Activiti5.22.0企业实战教程<流程挂起与激活篇>
  10. 腾讯第一大股东 Prosus 18亿美元收购 StackOverFlow
  11. AS3和Flex常用知识100条
  12. vue写一个简单的警察抓小偷的打字游戏
  13. 海康威视mp4html播放器,videoJS 网页视频播放器支持MP4
  14. 抽象代数之欧拉定理的群论的简短证明
  15. 全国2013年最新电子地图矢量数据超图格SGD MAPINFO GST SMW SHP格式等
  16. CSS font-family 属性值大全
  17. 第六章 人际关系的本质
  18. SQL server 期末复习
  19. 阿里云账号个人实名认证教程
  20. 显卡内存一直被占用解决方式

热门文章

  1. 装机员U盘启动PE制作工具V3.0(无广告无捆绑)
  2. SDUT 贪心商人小鑫
  3. WinCC V7.5 连接 S7-1200PLC 步骤
  4. 关于中国电信、中国联通5G网络的几点思考
  5. 浏览器的页面日志采集
  6. javaCV将socket获取的视频流推到流媒体(RTMP)服务器
  7. 线性代数导论17——正交矩阵和Gram-Schmidt正交化
  8. 仲联量行:科技行业繁荣推动深圳成为中国内地第三大办公楼市场
  9. 精挑细选的年度工作总结PPT模板
  10. Python 机器学习之分析和预测自杀倾向的人员(教程含源码)