当前位置: 首页 > news >正文

合众商道网站开发温州 网站建设

合众商道网站开发,温州 网站建设,沉默是金吉他谱,保险网站有哪些保险网站P1775 石子合并(弱化版) 题目描述 设有 N ( N ≤ 300 ) N(N \le 300) N(N≤300) 堆石子排成一排,其编号为 1 , 2 , 3 , ⋯ , N 1,2,3,\cdots,N 1,2,3,⋯,N。每堆石子有一定的质量 m i ( m i ≤ 1000 ) m_i\ (m_i \le 1000) mi​ (mi​≤…

P1775 石子合并(弱化版)

题目描述

设有 N ( N ≤ 300 ) N(N \le 300) N(N300) 堆石子排成一排,其编号为 1 , 2 , 3 , ⋯ , N 1,2,3,\cdots,N 1,2,3,,N。每堆石子有一定的质量 m i ( m i ≤ 1000 ) m_i\ (m_i \le 1000) mi (mi1000)。现在要将这 N N N 堆石子合并成为一堆。每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并后与这两堆石子相邻的石子将和新堆相邻。合并时由于选择的顺序不同,合并的总代价也不相同。试找出一种合理的方法,使总的代价最小,并输出最小代价。

输入格式

第一行,一个整数 N N N

第二行, N N N 个整数 m i m_i mi

输出格式

输出文件仅一个整数,也就是最小代价。

样例 #1

样例输入 #1

4
2 5 3 1

样例输出 #1

22

题解分析

这道题目可以通过区间动态规划来解决。我们的目标是将多个石子堆合并成一堆,而每次合并相邻的两堆所需要的代价是这两堆石子质量之和。因为每次合并顺序不同,总的合并代价也会不同,所以我们要找到一种顺序,使得总的合并代价最小。

动态规划状态定义

我们设 dp[i][j] 表示将第 i 堆到第 j 堆的石子合并成一堆的最小代价。这个问题的关键是,如何从已经合并好的子区间合并出更大的区间。

状态转移

  1. 初始状态

    • 对于任何单独的一堆石子,即 dp[i][i],合并代价为 0,因为它已经是一个单独的堆,不需要合并。
  2. 状态转移方程
    对于区间 [i, j],我们可以选择一个中间点 k 来分割区间 [i, j],使得左半部分是 [i, k],右半部分是 [k+1, j],然后将这两个子区间的结果合并。合并这两个子区间的代价为这两个子区间的质量和。

    因此,dp[i][j] 可以通过以下方式计算:
    d p [ i ] [ j ] = min ⁡ ( d p [ i ] [ k ] + d p [ k + 1 ] [ j ] + sum [ i , j ] ) 其中 k ∈ [ i , j − 1 ] dp[i][j] = \min(dp[i][k] + dp[k+1][j] + \text{sum}[i, j]) \quad \text{其中} \quad k \in [i, j-1] dp[i][j]=min(dp[i][k]+dp[k+1][j]+sum[i,j])其中k[i,j1]
    其中,sum[i, j] 表示从 ij 的石子质量之和。

  3. 如何计算区间的质量和?
    使用前缀和来快速计算任意区间 [i, j] 的石子质量和。前缀和数组 sum[i] 记录了从第 1 堆到第 i 堆的质量之和。通过前缀和,我们可以在常数时间内得到任意区间 [i, j] 的和:
    sum [ i , j ] = sum [ j ] − sum [ i − 1 ] \text{sum}[i, j] = \text{sum}[j] - \text{sum}[i-1] sum[i,j]=sum[j]sum[i1]

算法复杂度

  • 时间复杂度
    • 我们需要填充一个 dp 数组,其中有 O(N^2) 个状态。
    • 对于每一个 dp[i][j],我们需要枚举中间点 k,这使得每个状态的转移需要 O(N) 的时间。
    • 因此,总的时间复杂度是 O(N^3),其中 N 最大为 300,这使得该算法在给定输入限制下是可行的。

代码实现

#include <iostream>
#include <vector>
#include <algorithm>#define int long long
using namespace std;const int N = 300 + 10;
const int INF = 1e18;int dp[N][N];    // dp[i][j] 存储合并区间 [i, j] 的最小代价
int sum[N];      // sum[i] 存储从 1 到 i 的前缀和void solve() {int n;cin >> n;vector<int> v(n + 1);// 输入石子的质量for (int i = 1; i <= n; ++i) {cin >> v[i];}// 计算前缀和sum[0] = 0;for (int i = 1; i <= n; ++i) {sum[i] = sum[i - 1] + v[i];}// 初始化 dp 数组for (int i = 1; i <= n; ++i) {dp[i][i] = 0;  // 单个堆合并代价为0}// 动态规划计算for (int len = 2; len <= n; ++len) {  // len 表示区间长度for (int l = 1; l <= n - len + 1; ++l) {  // l 表示区间左端点int r = l + len - 1;  // r 表示区间右端点dp[l][r] = INF;  // 初始化为无穷大for (int k = l; k < r; ++k) {  // k 为中间点,分割区间dp[l][r] = min(dp[l][r], dp[l][k] + dp[k + 1][r] + sum[r] - sum[l - 1]);}}}// 输出最小代价cout << dp[1][n] << endl;
}signed main() {solve();return 0;
}

代码分析

  1. 输入和前缀和的计算

    • 我们先读取石子的质量,并计算出前缀和数组 sum[],这样可以快速计算任何区间 [i, j] 的石子质量和。
  2. 初始化动态规划数组

    • 对于每个区间 [i, i],即单独一堆石子,合并代价为 0,因此 dp[i][i] = 0
  3. 动态规划过程

    • 我们使用三重循环来计算所有区间的最小代价:
      • 外层循环遍历区间的长度 len
      • 中层循环遍历区间的左端点 l
      • 内层循环遍历中间点 k,将区间 [l, r] 分为 [l, k][k+1, r] 两个子区间,计算合并代价。
  4. 最小代价输出

    • 最终,dp[1][n] 即为将所有石子堆合并成一堆的最小代价。

复杂度分析

  • 时间复杂度:

    • O(N^3),其中 N 是石子的堆数。由于我们有三重循环,时间复杂度为 O(N^3),每次计算都需要 O(1) 的时间。
  • 空间复杂度:

    • O(N^2),因为 dp 数组的大小为 N x N,用于存储每个区间的最小合并代价。

总结

这道题目通过动态规划和前缀和技巧,能够有效地计算出合并所有石子堆的最小代价。虽然时间复杂度是 O(N^3),但由于 N 的最大值为 300,算法在时间限制内是可以接受的。

http://www.yayakq.cn/news/473716/

相关文章:

  • 郫县建设局网站网站设计公司杭州
  • 一个工厂做网站有什么好处电子商务网站建设的一般步骤有
  • html电子商务网站模板电商网站对比表
  • 西安网站建设 早晨建网站程序工具
  • 最好加盟网站建设网站图片加载优化
  • 网站建设发展wordpress百度熊掌号
  • 网站 租用服务器房城乡建设部网站
  • cms网站怎么制作泛解析对网站的影响
  • 过期网站查询农产品网站建设策划书范文
  • 太原建站方法网站制作电话
  • 网站建设网站需要什么常熟市做网站公司
  • 为什么网站设计很少全屏鲁山网站建设
  • 记账凭证做网站摘要怎么写深圳网站制作的公司有哪些
  • 网站后缀govwordpress开发实战
  • 买了虚拟主机怎么建设网站wordpress c
  • 网站开发入股合作分配比例中企动力做的网站被百度屏蔽
  • 湛江建设网站吕梁网站制作吕梁安全
  • 网站建设的实验小结上海网站建设技术指导公司
  • 怎么做社交网站引流到亚马逊五和网站建设
  • 又拍网站怎么做的网站开发合同管辖权异议
  • 视频网站亏钱为什么还要继续做哪个网站的图片可以做素材
  • 自己创建网站中核二三公司是国企还是央企
  • 郴州市北湖建设局网站变身小说网址wordpress
  • 柳市网站建设购物网站网页设计图片
  • 爱站网怎么用百度下载免费安装到桌面
  • 网站建设公司的重要性有关网站建设的书
  • 免费建网站 高校社团官方网站东莞大岭山网站制作
  • 网站制作租用空间怎么设置自己的网站
  • 佛山网站开发哪家好芜湖市住房和城乡建设厅网站首页
  • 做外包软件的网站射洪网站建设