一天中午,lc正在苦哈哈的青大运动ing。忽然,天色变暗,乌云翻滚,接着一道闪电划破天空,好巧不巧劈在了lc身上,lc顿时眼前一黑晕了过去。等他醒来时,眼前的世界已然大变。天非天,地非地。面前矗立着一块巨大的屏幕。屏幕上有一个长度为n的序列a,以及两个函数f与g。g(i,j)=a[min(i,j)+1]+...+a[max(i,j)],f(i,j)=(i-j)^2+g(i,j)^2。在屏幕下方还有一行小字“想要回到原来的世界吗?那就求出最小的f(i,j)吧(i!=j)”。lc的内心早已被“蚌埠住啦”所占据,所以你能帮他回到原来的世界吗?
输入格式:
第一行输入一个数n
之后输入n个数表示序列a
输出格式:
输出一行一个数表示最小的f(i,j)(i!=j)
输入样例:
4
1 0 0 -1
输出样例:
1
本题可以用分治方法去做,不过比较难,有兴趣的可以看一下牛客15052--求最值
这里分享一个简单的方法,时间复杂度略高一些
代码参考:
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
using ll = long long;
const int qq = 100005;
ll a[qq];
inline ll sqr(ll x){ return x*x;}//内联函数
int main()
{
int n;
cin >> n;
for(int i=1;i <= n;i++)
{
scanf("%lld",a + i);
a[i] += a[i-1];//这一步很妙
}
ll minans = INF;
for(int i=1;i <= n;i++)
{
int k=1;
for(int j=i-1;j >= 1&&k<50;j--,k++)//我的那个平台k取10的话有一个点超时,取50就可以全过,大家灵活取值
{
ll ans = sqr(i-j) + sqr(a[i]-a[j]);
if(ans < minans)
minans = ans;
}
}
cout << minans << endl;
return 0;
}