博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[NOI1995]石子合并
阅读量:7120 次
发布时间:2019-06-28

本文共 3938 字,大约阅读时间需要 13 分钟。

  题目描述

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

  输入输出格式

  输入格式:数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数.

  输出格式:输出共2行,第1行为最小得分,第2行为最大得分.

  输入输出样例

  输入样例:
1   42   4 5 9 4

 

  输出样例:
1   432   54

  这道题的动态规划还是很好想的~,这道题就是普通的区间dp。

  用point[i][j]来表示(i,j)区间内得分得最大值或最小值,然后用k将(i,j)区间分开,这个(i,j)区间得分的最大值(最小值)就是,对于k取(i,j)区间中的任意一个值时(i,k)区间和(k+1,j)区间相加的最大值(最小值)。如果(i,j)区间内只有两个值,则得分就是这两堆石头之和。

  dp方程:point[ i ][ j ] = max(min)(point[ i ][ j ] , point[ i ][ k ] + point[ k + 1 ][ j ]);

  这样就完事啦,但是要注意!!!这道题的石堆围成了个圈!!!(导致我第一次没过QAQ)

最后贴上自己的代码

1 #include
2 #include
3 using namespace std; 4 int N; 5 int stone[101]; 6 int point[101][101]; 7 int stoneSum[101][101]{ 0 }; 8 9 int max(int a, int b) { return a > b ? a : b; } 10 int min(int a, int b) { return a > b ? b : a; } 11 int partStoneMax(int front, int rear);//一个环切成两段 12 int partstonemax(int front, int rear); 13 int partStoneMin(int front, int rear);//同上 14 int partstonemin(int front, int rear); 15 16 int main() { 17 int sum; 18 cin >> N; 19 for (int i = 1; i <= N; i++) 20 cin >> stone[i]; 21 for (int i = 1; i <= N; i++) 22 for (int j = 1; j <= N; j++) 23 point[i][j] = -1; 24 for (int i = 1; i <= N; i++) 25 for (int j = 1; j <= N; j++) { 26 sum = 0; 27 int k = i; 28 while (1) { 29 sum += stone[k]; 30 if (k == j) break; 31 if (k == N) k = 0; 32 k++; 33 } 34 stoneSum[i][j] = sum; 35 } 36 cout << partStoneMin(1, N) << endl; 37 for (int i = 1; i <= N; i++) 38 for (int j = 1; j <= N; j++) 39 point[i][j] = -1; 40 cout << partStoneMax(1, N) << endl; 41 system("PAUSE"); 42 return 0; 43 } 44 45 int partStoneMax(int front, int rear) { 46 int p = 0, temp = 0; 47 for (int i = 1; i < N; i++) 48 for (int j = i; j < N; j++) { 49 temp = partstonemax(i, j) + partstonemax(j + 1, i - 1); 50 p = max(p, temp); 51 } 52 point[front][rear] = p + stoneSum[front][rear]; 53 return point[front][rear]; 54 } 55 56 int partstonemax(int front, int rear) { 57 if (front > N)front = 1; 58 if (rear < 1)rear = N; 59 int p = 0, k = front, temp; 60 if (point[front][rear] >= 0) 61 return point[front][rear]; 62 if (front == rear) { 63 point[front][rear] = 0; 64 return 0; 65 } 66 while (1) { 67 if (k == rear) break; 68 temp = partstonemax(front, k) + partstonemax(k + 1, rear); 69 p = max(p, temp); 70 if (k == N) k = 0; 71 k++; 72 } 73 p += stoneSum[front][rear]; 74 point[front][rear] = p; 75 return p; 76 } 77 78 int partStoneMin(int front, int rear) { 79 int p = 99999999, temp = 0; 80 for (int i = 1; i < N; i++) 81 for (int j = i; j < N; j++) { 82 temp = partstonemin(i, j) + partstonemin(j + 1, i - 1); 83 p = min(p, temp); 84 } 85 point[front][rear] = p + stoneSum[front][rear]; 86 return point[front][rear]; 87 } 88 89 int partstonemin(int front, int rear) { 90 if (front > N)front = 1; 91 if (rear < 1)rear = N; 92 int p = 99999999, k = front, temp; 93 if (point[front][rear] >= 0) 94 return point[front][rear]; 95 if (front == rear) { 96 point[front][rear] = 0; 97 return 0; 98 } 99 while (1) {100 if (k == rear) break;101 temp = partstonemin(front, k) + partstonemin(k + 1, rear);102 p = min(p, temp);103 if (k == N) k = 0;104 k++;105 }106 p += stoneSum[front][rear];107 point[front][rear] = p;108 return p;109 }

   只能想出ms的laji的我。。。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  我是萌新,我是萌新,不要说(我)代码了QAQ

转载于:https://www.cnblogs.com/DukeOfYork/p/10046500.html

你可能感兴趣的文章
12.24作业
查看>>
压力测试
查看>>
java异步发送邮件
查看>>
详细介绍java中的数据结构
查看>>
我的友情链接
查看>>
awk详解
查看>>
三、Harbor的工作流程
查看>>
命令解释器
查看>>
远程存储—删除时自动备份
查看>>
__FILE__,__LINE__
查看>>
oracle tns listener配置 (附TNS介绍)
查看>>
Java基础之面向对象2
查看>>
我的友情链接
查看>>
Makefile
查看>>
Spring Boot starter介绍
查看>>
集中式计算助力虚拟化桌面
查看>>
x86+NFV 中国电信成功构建中国首个IP智能管道
查看>>
java中clone详解
查看>>
saltstack入门系列(一) 安装和简单使用
查看>>
我的友情链接
查看>>