石子合并
来源:互联网 发布:知乎怎么打不开 编辑:程序博客网 时间:2024/04/29 23:19
在一个圆形操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分。
#include <stdio.h>#define N 100#define INF 65536 #define min(a,b) a<b?a:b#define max(a,b) a>b?a:bint MAX,MIN,a[N],n;int dp[N][N][2];//0代表最小值,1代表最大值int total(int i, int j){int total=0;for(int k=i;k<=j;k++)total += a[k];return total;}void function(){int i,j,k,len;for(i=1;i<=n;i++)dp[i][i][0] = dp[i][i][1] = 0;for(len=2;len<=n;len++)//有几堆合并for(i=1;i<=n-len+1;i++)//从第几堆开始{j=i+len-1;//到第几堆dp[i][j][0] = INF;dp[i][j][1] = -INF;for(k=i;k<j;k++){if(dp[i][k][0]+dp[k+1][j][0]+total(i,j) < dp[i][j][0])dp[i][j][0]=dp[i][k][0]+dp[k+1][j][0]+total(i,j);if(dp[i][k][1]+dp[k+1][j][1]+total(i,j) > dp[i][j][1])dp[i][j][1]=dp[i][k][1]+dp[k+1][j][1]+total(i,j);}}MAX = max(MAX,dp[1][n][1]);MIN = min(MIN,dp[1][n][0]);}int main(){int i;MAX = -INF, MIN = INF;printf("输入堆的个数:");scanf("%d",&n);printf("输入每堆石子个数:");for(i=1;i<=n;i++)scanf("%d",&a[i]);function();for(i=2;i<=n;i++)//圆圈拆成一根根的直线{int last = a[1];for(int j=2;j<=n;j++)a[j-1] = a[j];a[n] = last;function();}printf("最大值为:%d\n",MAX);printf("最小值为:%d\n",MIN);return 0;}
还有一种空间换时间方法,圆圈用两倍直线代替,比如圆圈长度为N,则用2N的数组表示
#include <stdio.h>#define N 100#define INF 65536 #define min(a,b) a<b?a:b#define max(a,b) a>b?a:bint MAX,MIN,a[N],n;int dp[N][N][2];//0代表最小值,1代表最大值int total(int i, int j){int total=0;for(int k=i;k<=j;k++)total += a[k];return total;}void function(){int i,j,k,len;for(i=1;i<=2*n;i++)dp[i][i][0] = dp[i][i][1] = 0;for(len=2;len<=n;len++)//有几堆合并for(i=1;i<=2*n-len+1;i++)//从第几堆开始{j=i+len-1;//到第几堆dp[i][j][0] = INF;dp[i][j][1] = -INF;for(k=i;k<j;k++){if(dp[i][k][0]+dp[k+1][j][0]+total(i,j) < dp[i][j][0])dp[i][j][0]=dp[i][k][0]+dp[k+1][j][0]+total(i,j);if(dp[i][k][1]+dp[k+1][j][1]+total(i,j) > dp[i][j][1])dp[i][j][1]=dp[i][k][1]+dp[k+1][j][1]+total(i,j);}}for(i=1;i<=n;i++){if(dp[i][i+n-1][0] < MIN)MIN = dp[i][i+n-1][0];if(dp[i][i+n-1][1] > MAX)MAX = dp[i][i+n-1][1];}}int main(){int i;MAX = -INF, MIN = INF;printf("输入堆的个数:");scanf("%d",&n);printf("输入每堆石子个数:");for(i=1;i<=n;i++)scanf("%d",&a[i]);for(i=n+1;i<=2*n;i++)//这里不同a[i] = a[i-n];function();printf("最大值为:%d\n",MAX);printf("最小值为:%d\n",MIN);return 0;}
- 石子-石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 【石子合并】
- 合并石子
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 合并石子
- 石子合并
- 合并石子
- jasig cas单点登录配置笔记之三
- 不一样的JavaScript(1)——循环
- POJ 2421
- fbx起航
- 在eclipse下创建maven项目并部署到tomcat服务器下
- 石子合并
- Android 常用代码---UI
- 动态创建的CListCtrl控件的消息响应
- 三角网绘制续
- 01.C++ book
- Excel中的STDEV.P和STDEV.S函数的区别
- 关于platform_driver 是如何匹配 platform_device的和如何调用到platform_driver中的probe函数的研究
- 好气色“吃”出来 7条守则缔造美肌—多喝水、喝对水
- 临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)的区别