SPOJ 345 Mixtures

题目传送门:进入

分析:

这道题是“石子合并”的变形。同样是用动态规划来解。

用 dp[i, j] 表示从第 i 堆开始的 j 堆混合物合并所释放的最少烟雾量

sum[i, k] 表示从第 i 堆开始的 j 堆混合物合并后的颜色。

显然有状态转移方程:

dp[i, j] = min { dp[i, k] + dp[i + k, j - k] + sum[i, k] * sum[i + k, j - k] }    (1 <= k < j)

由此不难写出代码:

01 #include <iostream>
02 #include <cstring>
03 #include <climits>
04 using namespace std;
05
06 int main(int argc, char *argv[])
07 {
08     ios::sync_with_stdio(false);
09     int i, j, k, m, temp;
10     int n;
11     int mix[101];
12     int dp[101][101];
13     int sum[101][101];
14
15     while (cin >> n)
16     {
17         memset(mix, 0, sizeof(mix));
18         memset(dp, 0, sizeof(dp));
19         memset(sum, 0, sizeof(sum));
20         for (i = 1; i <= n; ++i)
21         {
22             cin >> mix[i];
23             sum[i][1] = mix[i];
24             dp[i][1] = 0;
25         }
26         for (i = 1; i <= n; ++i)
27         {
28             for (j = 2; i + j <= n + 1; ++j)
29             {
30                 sum[i][j] = (sum[i][j - 1] + mix[i + j - 1]) % 100;
31             }
32         }
33
34         for (i = n; i >= 1; --i)
35         {
36             for (j = 2; i + j <= n + 1; ++j)
37             {
38                 m = INT_MAX;
39                 for (k = 1; k < j; ++k)
40                 {
41                     temp = dp[i][k] + dp[i + k][j - k] + sum[i][k] * sum[i + k][j - k];
42                     if (temp < m)
43                         m = temp;
44                 }
45                 dp[i][j] = m;
46             }
47         }
48         cout << dp[1][n] << endl;
49     }
50     return 0;
51 }
posted @ 2010-06-26 18:55  shilcare  阅读(365)  评论(0)    收藏  举报