石子合并/能量项链【区间dp】

题目链接:http://www.51mxd.cn/problem.php-pid=737.htm

题目大意:给出n个石子堆以及这n个石子堆中石子数目,每次操作合并两个相邻的石子堆,代价为两个石子堆数目之和,求最后合成一个石子堆时所花费的最小代价。

解题思路:典型的区间dp

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #define mem(a, b) memset(a, b, sizeof(a))
 5 const int MAXN = 220;
 6 const int inf = 0x3f3f3f3f;
 7 using namespace std;
 8 
 9 int arr[MAXN], sum[MAXN];
10 int dp[MAXN][MAXN]; //表示i ~ j区间内的最小代价 
11 
12 int main()
13 {
14     int n;
15     while(scanf("%d", &n) != EOF)
16     {
17         mem(dp, 0), mem(sum, 0);
18         for(int i = 1; i <= n; i ++)
19         {
20             scanf("%d", &arr[i]);
21             sum[i] += sum[i - 1] + arr[i];
22         }
23         for(int len = 2; len <= n; len ++) //枚举长度 
24         {
25             for(int i = 1; i + len - 1 <= n; i ++) // 枚举区间起点
26             {
27                 int j = i + len - 1; //区间终点
28                 dp[i][j] = inf;
29                 for(int k = i; k < j; k ++)
30                 {
31                     dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + sum[j] - sum[i - 1]);
32                 }
33             }
34         }
35         printf("%d\n", dp[1][n]);
36     }
37     return 0;
38 }
View Code

题目链接:https://ac.nowcoder.com/acm/contest/1089/J

题目大意:给出一个环形项链,每次操作合成两个相邻的宝珠,代价为两个宝珠首,中间,尾乘积,求最后合成一个宝珠时所花费的最小代价。

解题思路:

1.区间dp,破环成链,数组开2倍。

 1 #include<stdio.h>
 2 #define LL long long
 3 #include<math.h>
 4 #include<algorithm>
 5 using namespace std;
 6 const int MAXN = 220;
 7 
 8 int a[MAXN];
 9 LL dp[MAXN][MAXN];
10 
11 int main()
12 {
13     int n;
14     scanf("%d", &n);
15     for(int i = 1; i <= n; i ++)
16     {
17         scanf("%d", &a[i]);
18         a[i + n] = a[i];
19     }
20     for(int len = 2; len <= n; len ++) //枚举长度 
21     {
22         for(int i = 1; i + len - 1 <= 2 * n; i ++)  //枚举起点 
23         {
24             int j = i + len - 1;  //终点 
25             for(int k = i; k < j; k ++)
26             {
27                 dp[i][j] = max(dp[i][j], dp[i][k] + dp[k + 1][j] + a[i] * a[k + 1] * a[j + 1]);
28             }
29         }
30     }
31     LL ans = -1;
32     for(int i = 1; i <= n; i ++)
33         ans = max(ans, dp[i][i + n - 1]);
34     printf("%lld\n", ans);
35     return 0;
36 }
View Code

 

posted @ 2019-09-23 20:30  缘未到  阅读(227)  评论(0编辑  收藏  举报