这道题是2016年暑期多校训练第2场的第一题。说实话,像我这样的菜鸟做这样的题目,简直就是找虐╮(╯_╰)╭。不过还好第一题第一眼我就知道怎么做,纯粹是数学问题,然而第一次提交TLE,就开始想怎么快速求和。到后来看了学长的代码,才发现并不需要,只需逐项求和即可。结束后,自己试了一下,结果还是TLE,cin和cout换成scanf和printf后成功AC。吸取的最大教训就是少用C++的输入和输出,scanf、printf不知道比cin、cout快多少!!!
More specifically, you are given a weighted vector
W=(w1,w2,...,wn)
. Professor Zhang would like to find a binary vector
B=(b1,b2,...,bn)
(bi∈{+1,−1})
and a scaling factor
α≥0
in such a manner that
∥W−αB∥2
is minimum.
Note that ∥⋅∥ denotes the Euclidean norm (i.e. ∥X∥=x21+⋯+x2n−−−−−−−−−−√ , where X=(x1,x2,...,xn) ).
Note that ∥⋅∥ denotes the Euclidean norm (i.e. ∥X∥=x21+⋯+x2n−−−−−−−−−−√ , where X=(x1,x2,...,xn) ).
Input
There are multiple test cases. The first line of input contains an integer
T
, indicating the number of test cases. For each test case:
The first line contains an integers n (1≤n≤100000) -- the length of the vector. The next line contains n integers: w1,w2,...,wn (−10000≤wi≤10000) .
The first line contains an integers n (1≤n≤100000) -- the length of the vector. The next line contains n integers: w1,w2,...,wn (−10000≤wi≤10000) .
Output
For each test case, output the minimum value of
∥W−αB∥2
as an irreducible fraction "
p
/
q
" where
p
,
q
are integers,
q>0
.
Sample Input
3 4 1 2 3 4 4 2 2 2 2 5 5 6 2 3 4题目的大致意思就是求∑(w[i]-α*b[i])^2的最小值,其中w[i]为题目要输入的,b[i]只能是-1或1, α要求必须大于等于0.把那个式子展开,∑w[i]^2-2α∑w[i]*b[i]+α^2∑b[i]^2.所以要让那个式子尽可能小,则b[i]与w[i]异号。记s1=∑|w[i]|,s2=∑w[i]^2。式子化为n*α^2-2*α*s1+s2,其中s1和s2可以求出,就转换成求二次函数的极值。AC代码如下:#include<iostream> #include<cstdio> #include<cmath> using namespace std; typedef long long ll; int w[100005]; ll gcd(ll a,ll b) { return (b==0)?a:gcd(b,a%b); } int main() { int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); ll s1=0,s2=0; for(int i=0;i<n;i++){ scanf("%d",&w[i]); s1+=abs(w[i]); s2+=w[i]*w[i]; } ll p=n*s2-s1*s1; ll q=n; printf("%lld/%lld\n",p/gcd(p,q),q/gcd(p,q)); } return 0; }