大意为每个单位在不同位置有不同值(在关于位置的一个函数)此时只有把每个单位调到最合适的位置才能实现最小,因此为强排列
这里强排列的方法是两两调换(若出现更优情况进行调换)而其余情况为相对当前较优应当保持
而发现的不优单位当前的位置也不是一定是最优,所以要先对他进行调优再调整原单位直至不再出现更优调整下个(前面操作若将优者放好后续也无须再调)
因为单个调整完不一定是全局最优 所以当在后面发现前者不够优还要调整 直至最后结束递归使全局最优 而单个的影响不一定是全局的所以要遍历递归直至结束
这里的暴力强排序也是利用了这里n的小范围
代码:
#include<bits/stdc++.h>
using namespace std;
int n;
struct node{
long long z,v;
int po;
}c[305];
long long f(long long t ,node one)
{
return t*t*one.v*one.v+2*one.v*t*one.z;
}
void g(int p)
{
int t;
for(int i=0;i<n;++i)
{
if(c[i].po==p)
{
t=i;
break;
}
}
for(int i=0;i<n;++i)
{
if(f(i,c[i])+f(t,c[t])>f(t,c[i])+f(i,c[t]))
{
swap(c[i],c[t]);
g(c[t].po);
g(p);
}
}
}
int main ()
{
scanf("%d",&n);
int a,b,z,v;
long long ans=0;
for(int i=0;i<n;++i)
{
c[i].po=i;
scanf("%d%d%d%d",&a,&b,&z,&v);
ans+=(a*a+b*b+z*z);
c[i]={z,v,i};
}
for(int i=0;i<n;++i)
g(i);
for(int i=1;i<n;++i)
{
ans+=f(i,c[i]);
}
printf("%lld\n",ans);
return 0;
}