zoukankan      html  css  js  c++  java
  • 石子合并/能量项链【区间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
    ", 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
    ", ans);
    35     return 0;
    36 }
    View Code
  • 相关阅读:
    Socket_leaks open socket #5024 left in connection
    阿里云 如何减少备份使用量? mysql数据库的完整备份、差异备份、增量备份
    一个正则式引发的血案 贪婪、懒惰与独占
    linux下tmp目录里很多php开头的文件
    后端线上服务监控与报警方案
    架构先行
    数据盘缩容
    文件过滤 批量删除
    mock数据(模拟后台数据)
    如何避免升级 Linux 实例内核后无法启动
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/11574583.html
Copyright © 2011-2022 走看看