[CF460E]Roland and Rose
題意:給定$n$和$r$,要找$n$個整點(diǎn),使得他們兩兩距離的平方和最大,并且所有點(diǎn)到原點(diǎn)的距離必須小于$r$
很容易猜到答案在凸包上然后暴力找,但證明還是挺妙的
首先轉(zhuǎn)化一下距離平方和
令$\vec{a_i}=\vec{OA_i}$,則$\sum\limits_{i\lt j}A_iA_j^2=\dfrac{\sum\limits_{i\neq j}A_iA_j^2}{2}=\dfrac{\sum\limits_{i\neq j}(\vec{a_i}-\vec{a_j})^2}{2}=\dfrac{\sum\limits_{i\neq j}(\vec{a_i}^2+\vec{a_j}^2-2\cdot\vec{a_i}\cdot\vec{a_j})}{2}$
對于每個$k$,當(dāng)$i=k$時$\vec{a_k}^2$被計(jì)算$n-1$次,當(dāng)$i\neq k$時被計(jì)算$n-1$次
再用和的平方公式處理一下兩兩做點(diǎn)積的項(xiàng)
原式$=\dfrac{2(n-1)\sum\limits_{1\leq i\leq n}\vec{a_i}^2-2[(\sum\limits_{1\leq i\leq n}\vec{a_i})^2-\sum\limits_{1\leq i\leq n}\vec{a_i}^2]}{2}=n\sum\limits_{1\leq i\leq n}\vec{a_i}^2-(\sum\limits_{1\leq i\leq n}\vec{a_i})^2$
為了讓第一項(xiàng)盡可能大,選的點(diǎn)應(yīng)該盡可能遠(yuǎn)離原點(diǎn),為了讓第二項(xiàng)盡可能小,選的點(diǎn)應(yīng)該盡可能可以互相抵消(因?yàn)槭窍蛄亢?#xff09;
這提示了我們答案會分布在凸包上,下面我們來嚴(yán)格證明
假設(shè)已經(jīng)確定了$A_{1\cdots n-1}$我們想確定最后一個點(diǎn),設(shè)它為$P(x,y)$
新增加的距離平方和為$\sum\limits_{1\leq i\leq n-1}[(x-x_i)^2+(y-y_i)^2]$
整理一下,得到$(n-1)[(x-\frac{\sum\limits_{1\leq i\leq n-1}x_i}{n-1})^2-(\frac{\sum\limits_{1\leq i\leq n-1}x_i}{n-1})^2+\frac{\sum\limits_{1\leq i\leq n-1}x_i^2}{n-1}+(y-\frac{\sum\limits_{1\leq i\leq n-1}y_i}{n-1})^2-(\frac{\sum\limits_{1\leq i\leq n-1}y_i}{n-1})^2+\frac{\sum\limits_{1\leq i\leq n-1}y_i^2}{n-1}]$
后面那一大坨東西跟$x,y$無關(guān),所以問題轉(zhuǎn)換為求離$X(\dfrac{\sum\limits_{1\leq i\leq n-1}x_i}{n-1},\dfrac{\sum\limits_{1\leq i\leq n-1}y_i}{n-1})$最遠(yuǎn)的點(diǎn)
下面證$P$在凸包端點(diǎn)上
假設(shè)$P$不在凸包端點(diǎn)上,延長$XP$與凸包某邊$AB$交于$P'$(交于端點(diǎn)直接取端點(diǎn)為更優(yōu)解)
若$\angle AP'X\geq\dfrac{\pi}{2}$,則$AX\gt XP'\gt XP$,即選$A$更優(yōu)
若$\angle BP'X\geq\dfrac{\pi}{2}$,則$BX\gt XP'\gt XP$,即選$B$更優(yōu)
就這樣證完了
所以一開始找一下凸包,然后暴力找到最優(yōu)解
算一下就知道$r=29$的時候凸包的點(diǎn)數(shù)量最多,有$36$個,一點(diǎn)都不虛其實(shí)還是得感謝CF的評測機(jī)
我居然能找到一道Div2的E是暴力23333
#include<stdio.h> #include<math.h> #include<vector> using namespace std; struct point{int x,y;point(int a=0,int b=0){x=a;y=b;} }t; point operator-(point a,point b){return point(a.x-b.x,a.y-b.y); } int operator*(point a,point b){return a.x*b.y-a.y*b.x; } vector<point>p; vector<int>now,bes; int n,r,ans; void dfs(int chos,int las,int sx,int sy,int sx2,int sy2){if(chos==n){if(ans<n*(sx2+sy2)-sx*sx-sy*sy){ans=n*(sx2+sy2)-sx*sx-sy*sy;bes=now;}return;}for(int i=las;i<p.size();i++){now.push_back(i);dfs(chos+1,i,sx+p[i].x,sy+p[i].y,sx2+p[i].x*p[i].x,sy2+p[i].y*p[i].y);now.pop_back();} } int main(){scanf("%d%d",&n,&r);int i,s;for(i=-r;i<=0;i++){p.push_back(point(i,(int)sqrt(r*r-i*i)));while(p.size()>2&&(p[p.size()-2]-p[p.size()-3])*(p[p.size()-1]-p[p.size()-2])>=0){p[p.size()-2]=p[p.size()-1];p.pop_back();}}s=p.size();for(i=s-2;i>=0;i--)p.push_back(point(-p[i].x,p[i].y));for(i=1;i<s;i++)p.push_back(point(-p[i].x,-p[i].y));for(i=s-2;i>0;i--)p.push_back(point(p[i].x,-p[i].y));ans=0;dfs(0,0,0,0,0,0);printf("%d\n",ans);for(i=0;i<n;i++)printf("%d %d\n",p[bes[i]].x,p[bes[i]].y); }轉(zhuǎn)載于:https://www.cnblogs.com/jefflyy/p/7952930.html
總結(jié)
以上是生活随笔為你收集整理的[CF460E]Roland and Rose的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java基础】Java基本数据类型与位
- 下一篇: EJS 模板中,js 如何获取后端传来的