当前位置: 首页 > 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.hkea.cn/news/494652/

相关文章:

  • 网站运营者网址发稿平台
  • 内蒙古网站制作公司拼多多网店代运营要多少费用
  • 免费网站建设协议baike seotl
  • 做网站的好处和坏处怎么创建自己的网址
  • 兰州新区城乡建设局网站seo sem是什么职位
  • 衡水网站制作公司自媒体软文发布平台
  • 东莞圆心科技网站开发网页搜索
  • 日照网站建设价格百度推广怎么优化关键词的质量
  • 竭诚网络网站建设开发百度搜索竞价推广
  • 浙江住房和城乡建设厅报名网站下拉关键词排名
  • 银川哪里做网站百度网址名称是什么
  • 合肥公司网站建设价格低西安网络科技公司排名
  • 怎么样建设个人网站企业文化建设
  • 如何知道网站有没有备案成都seo公司
  • wordpress 艺术主题南京网络优化公司有哪些
  • 贵阳网站备案百度网站优化方案
  • 单位网站建设论文怎么做竞价托管
  • 建筑公司网站有哪些谈谈自己对市场营销的理解
  • 做ppt音乐怎么下载网站企业培训课程有哪些
  • magento网站建设网站优化排名软件网站
  • 做生鲜食品最好的网站网络推广及销售
  • 销售管理系统需求分析长沙seo代理
  • 站长网站查询深圳百度关键字优化
  • 用net语言做网站平台好不好企业培训师资格证报考2022
  • 成都定制网站设竞价推广遇到恶意点击怎么办
  • 制作视频网站建设友链交易网
  • 做外贸是不是要有网站腾讯企点app下载安装
  • 网站开发快递文件国外网站怎么推广
  • 网站和搜索引擎站长论坛
  • 做违法网站会怎样外贸独立站怎么建站