[NOI1995]石子合并

  题目描述

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

  输入输出格式

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

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

  输入输出样例

  输入样例:
1   4
2   4 5 9 4

 

  输出样例:
1   43
2   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<iostream>
  2 #include<stdlib.h>
  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

posted @ 2018-11-30 21:04  DukeOfYork  阅读(265)  评论(0)    收藏  举报