超级胶水(第十一届蓝桥杯)

题目

小明有 n n n颗石子,按顺序摆成一排。他准备用胶水将这些石子粘在一起。

每颗石子有自己的重量,如果将两颗石子粘在一起,将合并成一颗新的石子,重量是这两颗石子的重量之和。

为了保证石子粘贴牢固,粘贴两颗石子所需要的胶水与两颗石子的重量乘积成正比,本题不考虑物理单位,认为所需要的胶水在数值上等于两颗石子重量的乘积。

每次合并,小明只能合并位置相邻的两颗石子,并将合并出的新石子放在原来的位置。

现在,小明想用最少的胶水将所有石子粘在一起,请帮助小明计算最少需要多少胶水。

输入格式

输入的第一行包含一个整数 n n n,表示初始时的石子数量。

第二行包含 n 个整数 w 1 , w 2 , ... , w n n个整数 w_1,w_2,...,w_n n个整数w1,w2,...,wn,依次表示每颗石子的重量。

输出格式

一个整数表示答案。

数据范围
1 ≤ n ≤ 1 0 5 , 1≤n≤10^5, 1≤n≤105,
1 ≤ w i ≤ 1000 1≤w_i≤1000 1≤wi≤1000
输入样例1:

3

3 4 5

输出样例1:

47

输入样例2:

8

1 5 2 6 3 7 4 8

输出样例2:

546

代码(python版本)

python 复制代码
n=int(input())
arr=list(map(int,input().split()))
res=0
cur=0
for i in range(len(arr)):
    res+=cur*arr[i]
    cur+=arr[i]
print(res)

代码(cpp版本)

cpp 复制代码
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

int n;
const int N = 1e5+10;
int arr[N];
int main()
{
    cin>>n;
    for (int i = 0; i < n; i ++ )
    cin>>arr[i];
    
    LL res=0,cur=0;    
    for (int i = 0; i < n; i ++ )
    {
        
        res+=cur*arr[i];
        cur+=arr[i];
    }
    cout<<res<<endl;
    
    
    return 0;
}

思路

看到这题,首先看一下数据范围为1e5,思考一下,那么最大的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),最多时间不能超过这个。现在心里有数了,就可以开始做题,首先拿到题目,首先暴力骗分 看一下常规思路。我们先模拟一下:

假设现在有 个石头,质量分别为 a 1 , a 2 , a 3 a_1,a_2,a_3 a1,a2,a3,那么:

第一次将最左边的两个石头合并,需要的胶水量就是 a 1 ∗ a 2 a_1*a_2 a1∗a2

现在只有两个石头了,质量分别为 a 1 + a 2 , a 3 a_1+a_2,a_3 a1+a2,a3

那么将这两个石头合并之后,需要的胶水量是 ( a 1 + a 2 ) ∗ a 3 (a_1+a_2)*a_3 (a1+a2)∗a3

一共需要的胶水量是 a 1 ∗ a 2 + ( a 1 + a 2 ) ∗ a 3 a_1*a_2+(a_1+a_2)*a_3 a1∗a2+(a1+a2)∗a3

假设现在有 个石头,质量分别为 a 1 , a 2 , a 3 , a 4 a_1,a_2,a_3,a_4 a1,a2,a3,a4,那么:

第一次将最左边的两个石头合并,需要的胶水量就是 a 1 ∗ a 2 a_1*a_2 a1∗a2

现在还有三个石头,质量分别为 a 1 + a 2 , a 3 , a 4 a_1+a_2,a_3,a_4 a1+a2,a3,a4

继续将左边的两个石头合并之后,需要的胶水量是 ( a 1 + a 2 ) ∗ a 3 (a_1+a_2)*a_3 (a1+a2)∗a3

现在只有两个石头,质量分别为 a 1 + a 2 + a 3 , a 4 a_1+a_2+a_3,a_4 a1+a2+a3,a4

将剩余的两个石头合并,需要的胶水量是 ( a 1 + a 2 + a 3 ) ∗ a 4 (a_1+a_2+a_3)*a_4 (a1+a2+a3)∗a4

一共需要的胶水量是 a 1 ∗ a 2 + ( a 1 + a 2 ) ∗ a 3 + ( a 1 + a 2 + a 3 ) ∗ a 4 a_1*a_2+(a_1+a_2)*a_3+(a_1+a_2+a_3)*a_4 a1∗a2+(a1+a2)∗a3+(a1+a2+a3)∗a4

到这里就找到了规律,就是胶水量为 a 1 ∗ a 2 + ( a 1 + a 2 ) ∗ a 3 + ( a 1 + a 2 + a 3 ) ∗ a 4 + ( a 1 + a 2 + a 3 + a 4 ) ∗ a 5 + . . . . . . + ( a 1 + a 2 + . . . + a n − 1 ) ∗ a n a_1*a_2+(a_1+a_2)*a_3+(a_1+a_2+a_3)*a_4+(a_1+a_2+a_3+a_4)*a_5+......+(a_1+a_2+...+a_{n-1})*a_n a1∗a2+(a1+a2)∗a3+(a1+a2+a3)∗a4+(a1+a2+a3+a4)∗a5+......+(a1+a2+...+an−1)∗an

然后代码中cur代表当前的重量,也就是上面的规律中的括号中的数。

相关推荐
爱吃涮毛肚的肥肥(暂时吃不了版)1 小时前
仿腾讯会议——音频服务器部分
c++·qt·面试·职场和发展·音视频·腾讯会议
智驱力人工智能2 小时前
AI移动监测:仓储环境安全的“全天候守护者”
人工智能·算法·安全·边缘计算·行为识别·移动监测·动物检测
代码小将3 小时前
力扣992做题笔记
算法·leetcode
编程绿豆侠3 小时前
力扣HOT100之二叉树:199. 二叉树的右视图
算法·leetcode·职场和发展
飞川撸码4 小时前
【LeetCode 热题100】17:电话号码的字母组合(详细解析)(Go语言版)
算法·leetcode·golang·dfs
蒟蒻小袁4 小时前
力扣面试150题--从前序与中序遍历序列构造二叉树
算法·leetcode·面试
闭月之泪舞5 小时前
初识函数------了解函数的定义、函数的参数、函数的返回值、说明文档的书写、函数的嵌套使用、变量的作用域(全局变量与局部变量)
python·算法·机器学习
软件测试曦曦5 小时前
15:00开始面试,15:06就出来了,问的问题有点变态。。。
自动化测试·软件测试·功能测试·程序人生·面试·职场和发展
GUIQU.5 小时前
【每日一题丨2025年5.12~5.18】排序相关题
算法·排序·每日一题
哪 吒5 小时前
2025B卷 - 华为OD机试七日集训第2期 - 按算法分类,由易到难,循序渐进,玩转OD(Python/JS/C/C++)
python·算法·华为od·华为od机试·2025b卷