码迷,mamicode.com
首页 > 其他好文 > 详细

DP经典题型:石子合并问题

时间:2014-07-12 09:03:38      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   strong   os   

本周集训专题为DP系列,一个经典的系列便是石子归并问题。

(1)有N堆石子,现要将石子有序的合并成一堆,规定如下:每次只能移动相邻的2堆石子合并,合并花费为新合成的一堆石子的数量。求将这N堆石子合并成一堆的总花费最小(或最大)。

 

这是石子归并的简化版本,石子处于一排。由于发现只能是相邻的2堆石子进行归并。我们会发现,贪心算法在此处便失去作用,局部最优解并不能带来整体最优解。

 

因此,不难让我们想到,此题应该采取DP(dynamic Programing)来求其最优解。

 

动态规划常常采取从部分整体最优解的拆分来得到最优解法的递归式,我们可以想到,此处是由2堆石子合并,所以最终最优解肯定是由两个局部最优解的加上整体的和求得。

 

因此,我们可以推断出动态转移方程:

bubuko.com,布布扣

dp[i][j]在此处表示从第i堆加到第j堆的最优解,而当i == j是,并不存在相加,所以结果为0.

 

(2)将上述问题从一排改为环形,便是完整版本的石子合并问题了。

 bubuko.com,布布扣

不难发现,其实解法类似。不过由于是环形,我们要在每次相加只有都对个数取余数,以防止数组越界。

bubuko.com,布布扣

 

不过,此处的j与前面(1)中的j意义并不一样,此处的j意义为:从第i堆出发,往下数j堆石子。因此,j == 0时,自然dp[i][j] == 0了

 

因为j的意义不同,所以dp[i][j]长得自然不一样了,实际上还是一个意思。

 

所以sum[i][j]也改为:

bubuko.com,布布扣

附上求最小值的代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <limits>
 4 using namespace std;
 5 const int INF = INT_MAX;
 6 const int maxn = 1003;
 7 int dp[maxn][maxn];
 8 int stone[maxn];
 9 int sum[maxn]; //0 - i 的和
10 int n; //本次的个数
11 int getSum(int i, int j) {
12     if (i + j >= n)
13         return getSum(i, n - i - 1) + getSum(0, i + j - n);
14     else
15         return sum[i + j] - (i > 0 ? sum[i - 1] : 0);
16 }
17 int findMin() {
18     for (int i = 0; i < n; i++) {
19         dp[i][0] = 0;
20     }
21     for (int j = 1; j < n; j++) {
22         for (int i = 0; i < n; i++) {
23             dp[i][j] = INF;
24 
25             for (int k = 0; k < j; k++) {
26                 dp[i][j] = min(dp[i][j], dp[i][k] + dp[(i + k + 1) % n][j - k - 1] + getSum(i, j));
27             }
28         }
29     }
30     return dp[0][n - 1];
31 }
32 
33 int main() {
34     while (cin >> n) {
35         for (int i = 0; i < n; i++) {
36             cin >> stone[i];
37             sum[i] = 0;
38         }
39         sum[0] = stone[0];
40         for (int i = 1; i < n; i++) {
41             sum[i] = sum[i - 1] + stone[i];
42         }
43         cout << findMin() << endl;
44     }
45     return 0;
46 }

 

 

                                                      

                                                      Vane_Tse On the Road.      2014-07-10   10:04:43

 

 

DP经典题型:石子合并问题,布布扣,bubuko.com

DP经典题型:石子合并问题

标签:style   blog   http   color   strong   os   

原文地址:http://www.cnblogs.com/slimjerk/p/3835131.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!