思路
观察两堆石子合并的时候,消耗就是两个石子堆的重量相乘,这样可以看成一个石子堆中所有的小石子乘另一个石子堆中所有的小石子,之后两个石子堆合成一个石子堆。我们往下继续思考,可以发现,两个小石子(不管在什么位置)合并操作就是一次乘法操作,每个小石子之间都会合并一次,所以最终的结果就是每个不同石子重量乘的和。
代码
#include<iostream>
long long s[100010];
using namespace std;
int n;
int main(){
cin>>n;
for(int i=1;i<=n;i++) {
cin>>s[i];
s[i]+=s[i-1];
}
long long sum=0;
for(int i=0;i<n;i++)
sum+=(s[i]-s[i-1])*(s[n]-s[i]);
cout<<sum;
return 0;
}
大佬请问这个能否用乘法结合律来解释
为啥前缀和也要开long long 啊,s[n]最大是10^5*10^3=1e8<1e9啊,但是我用int开s确实过不了 悲),求回复
大概是因为s[i] * s[i]的结果是先存在s[i]的类型里的,也就是int里,虽然每个s[i]都小于int,但是乘完就大于int了,所以不开ll的话,记得在乘的前面先乘个1ll
那这么说的话这题是不是不存在什么最小代价一说,因为无论怎么合并结果都是一样的对吗
是的
代码和解释的都挺清晰的
像是前缀和