[题解]CQOI2012 T2 组装 assemble
組裝 assemble
【題目描述】
數軸上有m個生產車間可以生產零件。一共有n種零件,編號為1~n。第i個車間的坐標為xi,生產第pi種零件(1<=pi<=n)。你需要在數軸上的某個位置修建一個組裝車間,把這些零件組裝起來。為了節約運輸成本,你需要最小化cost(1)+cost(2)+…+cost(n),其中cost(x)表示生產第x種零件的車間中,到組裝車間距離的平方的最小值。
【輸入】
?
輸入第一行為兩個整數n,?m,即零件的種類數和生產車間的個數。以下m行每行兩個整數xi和pi(1<=pi<=n)。輸入按照生產車間從左到右的順序排列(即xi<=xi+1。注意車間位置可以重復)。輸入保證每種零件都有車間生產。
【輸出】
輸出僅一行,即組裝車間的最優位置(可以和某個生產車間重合),四舍五入保留四位小數。輸入保證最優位置惟一。
【樣例】
assemble1.in
3 5
-1 3
0 1
2 3
4 2
5 2
assemble1.out
2.0000
?
assemble2.in
4 8
-10 2
-8 1
-5 1
-1 3
3 4
4 3
6 2
9 4
assemble2.out
0.7500
【數據規模】
| 編號 | 1-4 | 5-10 |
| n | <=15 | <=10000 |
| m | <=25 | <=100000 |
| xi | <=100 | <=100000 |
?-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
【題解】
??? 還是一道比較簡單的題目,感覺是在考數感。。注意題目要求的最終答案相當于是使選出的n個數的方差的n倍最小的位置。對于方差由兩個公式,這里我用的第二個公式,方便維護。給出維基上方差的鏈接:http://zh.wikipedia.org/wiki/%E6%96%B9%E5%B7%AE
??? 用一個結構體數組a[]保存一個偽鏈表。包括兩個關鍵字,第一個為生產某種零件的車間位置,第二關鍵字為生產同種零件的下一個車間的位置。然后排序,按照兩個關鍵字之和從小到大排序,即按照它們的終點坐標排序。(為什么自己想)默認第一次選出的n個車間為生產每一種零件的第一個車間,計算出總花費以及位置,然后從前往后掃a[],依次改變某一個車間的位置,更新總花費。
??? 不多贅述了,個人認為代碼寫得還不錯。望引玉>_<
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define MAXM 100020 7 #define MAXN 10020 8 typedef long long llt; 9 int n,m; 10 struct node 11 { 12 llt x,next; 13 }; 14 node a[MAXM]; 15 int In; 16 int Pos[MAXN],INF; 17 llt Sum1,Sum2; 18 bool Cmp(node a,node b) 19 { 20 return (a.x+a.next)<(b.x+b.next); 21 } 22 inline void Get_int(int &Ret) 23 { 24 char ch; 25 bool flag=false; 26 for(;ch=getchar(),ch<'0'||ch>'9';) 27 if(ch=='-') 28 flag=true; 29 for(Ret=ch-'0';ch=getchar(),ch>='0'&&ch<='9';Ret=Ret*10+ch-'0'); 30 flag&&(Ret=-Ret); 31 } 32 void Read() 33 { 34 Get_int(n); 35 Get_int(m); 36 int i,xi,pi; 37 memset(Pos,0x3f,sizeof(Pos)); 38 INF=Pos[0]; 39 for(i=1;i<=m;i++) 40 { 41 Get_int(xi); 42 Get_int(pi); 43 if(Pos[pi]==INF) 44 { 45 Sum1+=xi; 46 Sum2+=xi*xi; 47 } 48 else 49 { 50 a[++In].x=Pos[pi]; 51 a[In].next=xi; 52 } 53 Pos[pi]=xi; 54 } 55 sort(a+1,a+1+In,Cmp); 56 } 57 void Work() 58 { 59 //fang cha >_< _______orz 60 llt tmp=(llt)n*Sum2-Sum1*Sum1,_tmp; 61 //tmp=Sum2-(Sum1/n*Sum1/n)*n; 62 llt ans=Sum1; 63 //ans=Sum1/n; 64 int i; 65 for(i=1;i<=In;i++) 66 { 67 if(a[i].x==a[i].next) 68 continue; 69 Sum1+=(a[i].next-a[i].x); 70 Sum2+=(a[i].next*a[i].next-a[i].x*a[i].x); 71 _tmp=n*Sum2-Sum1*Sum1; 72 if(tmp>_tmp) 73 { 74 tmp=_tmp; 75 ans=Sum1; 76 } 77 } 78 printf("%.4lf\n",(double)ans/(double)n); 79 } 80 int main() 81 { 82 //freopen("assemble.in","r",stdin); 83 //freopen("assemble.out","w",stdout); 84 Read(); 85 Work(); 86 return 0; 87 }?
?
?
轉載于:https://www.cnblogs.com/CQBZOIer-zyy/archive/2013/01/14/2860374.html
總結
以上是生活随笔為你收集整理的[题解]CQOI2012 T2 组装 assemble的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MinGW下静态编译、链接Qt 5.0
- 下一篇: poj1151