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

长春老火车站百度seo排名优化排行

长春老火车站,百度seo排名优化排行,北京网站设计与制作公司,买做指甲的材料在哪个网站[NOI1995] 石子合并 题目描述 在一个圆形操场的四周摆放 N N N 堆石子,现要将石子有次序地合并成一堆,规定每次只能选相邻的 2 2 2 堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。 试设计出一个算法,计算出将 …

[NOI1995] 石子合并

题目描述

在一个圆形操场的四周摆放 N N N 堆石子,现要将石子有次序地合并成一堆,规定每次只能选相邻的 2 2 2 堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。

试设计出一个算法,计算出将 N N N 堆石子合并成 1 1 1 堆的最小得分和最大得分。

输入格式

数据的第 1 1 1 行是正整数 N N N,表示有 N N N 堆石子。

2 2 2 行有 N N N 个整数,第 i i i 个整数 a i a_i ai 表示第 i i i 堆石子的个数。

输出格式

输出共 2 2 2 行,第 1 1 1 行为最小得分,第 2 2 2 行为最大得分。

样例 #1

样例输入 #1

4
4 5 9 4

样例输出 #1

43
54

提示

1 ≤ N ≤ 100 1\leq N\leq 100 1N100 0 ≤ a i ≤ 20 0\leq a_i\leq 20 0ai20

题目大意

在一个圆形操场的四周摆放了 N N N 堆石子。每次操作中,你只能选择相邻的两堆石子进行合并,并且合并的得分是这两堆石子的数量之和。最终的目标是将所有石子合并为一堆,要求你计算出合并过程中得到的最小得分和最大得分。

解题思路

这道题目涉及到动态规划(Dynamic Programming, DP)和圆形排列的处理。我们可以将圆形的石子排列“展平”成一条线,并使用动态规划解决合并过程中的最小得分和最大得分问题。具体步骤如下:

  1. 展平圆形结构:由于石子的排列是圆形的,我们可以通过将数组复制一遍并拼接起来,变成一个长度为 2 N 2N 2N 的数组。这样,我们就可以将圆形结构当作一个线性结构来处理。

  2. 动态规划状态定义

    • dp1[l][r]:表示在区间 [ l , r ] [l, r] [l,r] 内合并所有石子的最小得分。
    • dp2[l][r]:表示在区间 [ l , r ] [l, r] [l,r] 内合并所有石子的最大得分。
  3. 状态转移方程

    • 计算最小得分时,我们可以选择区间内的任意一个位置进行合并,更新dp1[l][r]
      [
      dp1[l][r] = \min(dp1[l][r], dp1[l][k] + dp1[k+1][r] + sum[r] - sum[l-1])
      ]
    • 同样地,计算最大得分时更新dp2[l][r]
      [
      dp2[l][r] = \max(dp2[l][r], dp2[l][k] + dp2[k+1][r] + sum[r] - sum[l-1])
      ]
  4. 前缀和的计算:为了更快速地计算区间和,我们可以使用一个sum数组,其中sum[i]表示从第一个石子到第 i i i 个石子的总和。

  5. 最终结果:由于是一个环形结构,我们需要对dp1dp2中所有可能的区间(长度为 N N N 的子区间)计算最小值和最大值。

代码分析

#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
using namespace std;const int inf = 1e9 + 7;
const int N = 300 + 10;int n;
int dp1[N][N];  // 最小得分 DP
int dp2[N][N];  // 最大得分 DP
int sum[N];     // 前缀和数组
vector<int> v(N);  // 石子的数量void clear() {for (int i = 0; i < N; ++i) {for (int j = i; j < N; ++j) {if (i == j) {dp1[i][j] = 0;dp2[i][j] = 0;} else {dp1[i][j] = inf;dp2[i][j] = -inf;}}}
}void solved() {clear();cin >> n;  // 读入石子的堆数for (int i = 1; i <= n; ++i) {cin >> v[i];sum[i] = sum[i - 1] + v[i];  // 计算前缀和}// 扩展石子数组,处理圆形结构for (int i = n + 1; i <= 2 * n; ++i) {v[i] = v[i - n];sum[i] = sum[i - 1] + v[i];}// 计算 dp 数组for (int len = 2; len <= n; ++len) {  // 长度从2到nfor (int l = 1; l <= 2 * n - len + 1; ++l) {  // 枚举区间起始位置int r = l + len - 1;  // 区间的右端for (int k = l; k < r; ++k) {  // 枚举分割点dp1[l][r] = min(dp1[l][r], dp1[l][k] + dp1[k + 1][r] + sum[r] - sum[l - 1]);dp2[l][r] = max(dp2[l][r], dp2[l][k] + dp2[k + 1][r] + sum[r] - sum[l - 1]);}}}int minn = inf, maxx = -inf;for (int l = 1; l <= n; ++l) {  // 最终结果遍历所有可能的起始位置minn = min(minn, dp1[l][l + n - 1]);maxx = max(maxx, dp2[l][l + n - 1]);}cout << minn << endl;  // 输出最小得分cout << maxx << endl;  // 输出最大得分
}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int T = 1;while (T--) {solved();}
}

代码分析

  1. 初始化和前缀和:首先初始化 dp1dp2 数组,dp1[i][j] 用于保存区间 [ i , j ] [i, j] [i,j] 的最小合并得分,dp2[i][j] 用于保存区间 [ i , j ] [i, j] [i,j] 的最大合并得分。我们也通过 sum 数组计算了从第一个石子到第 i i i 个石子的前缀和。

  2. 展开圆形数组:由于问题中石子是圆形排列的,我们通过将数组从头到尾复制一次,形成一个长度为 2 N 2N 2N 的新数组 v,并且更新对应的前缀和 sum

  3. 动态规划计算:通过枚举区间长度 len 和起始位置 l,以及每个区间内的分割点 k,使用状态转移方程更新 dp1dp2 数组。最终,通过遍历所有可能的区间,找到最小得分和最大得分。

  4. 时间复杂度:由于有三重循环(区间长度、区间起点、分割点),时间复杂度为 O ( N 3 ) O(N^3) O(N3)。对于 N ≤ 100 N \leq 100 N100,这种复杂度是可以接受的。

总结

这个问题的核心在于如何利用动态规划求解合并石子的最小和最大得分。通过将圆形结构展开为线性结构,可以简化问题的求解。算法通过动态规划计算每个区间的最小和最大得分,并最终遍历所有可能的区间来求解答案。

http://www.hkea.cn/news/879674/

相关文章:

  • 创意建站推荐百度做广告多少钱一天
  • 巴中网站建设公司百度seo怎么做网站内容优化
  • 查网站备案名称上海网络营销seo
  • 人是用什么做的视频网站网络营销方案设计毕业设计
  • 建设网站考虑因素关键词优化是怎么弄的
  • 陕西营销型网站建设推广普通话的内容简短
  • 做配电箱的专门网站百度指数属于行业趋势及人群
  • 学做网站的网站重庆seo整站优化报价
  • 保定网站设计概述seo推广软件排名
  • 查pv uv的网站网络营销推广服务
  • 怎样让客户做网站优化 保证排名
  • 企业营销型网站做的好网络营销的有哪些特点
  • 网站开发 合同兰州快速seo整站优化招商
  • 网站开发技术现状深圳网络营销推广培训
  • 知名网络公司有哪些河北网站seo
  • 学做网站多少钱关键词难易度分析
  • 传奇如何做网站网站建设策划书案例
  • 龙岗 网站建设深圳信科最好用的搜索神器
  • 动态网站开发日志重庆seo整站优化报价
  • 魔站网站建设微信公众号运营推广方案
  • 好的网站建设公司营销推广外包公司
  • 教育机构做网站素材长尾关键词爱站
  • 做网站选什么系统企业网站seo推广
  • 山东省南水北调建设管理局网站腾讯网qq网站
  • 菏泽做网站公司sem网络营销
  • 专业建站外包兰州网络优化seo
  • 企业邮箱腾讯杭州seo按天计费
  • 政府网站建设先进个人事迹互动营销
  • 网站建设之织梦模板做国外网站
  • 小程序电商模板seo关键词排名优化品牌