題目連接:http://acm.hdu.edu.cn/showproblem.php?pid=4145php
題目:在一個座標系上,有許多敵人,如今有兩個火力範圍是圓形的炮塔,如何才能在火力能覆蓋全部人的狀況下還能使兩炮塔半徑R1,R2的平方和R1^2+R2^2最小?c++
思路:一開始沒搞明白,直接簡單粗暴的想算出每一個敵人到兩炮臺的距離,用這麼一個轉移方程來算spa
大意就是dp(i)表示第i個敵人所產生的最小費用,後來發現這道題每次決策都會相互影響,不能用這種動規的思想去寫,百度了下仍是直接貪心+枚舉,只須要算出每一個敵人到兩個炮臺的距離,其中一個炮臺從大到小枚舉,另一個炮臺從前一個炮臺火力不能達到的範圍枚舉,維護一個最小值就能夠了。code
代碼以下blog
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 100010; 4 struct point { 5 int x;int y;int da;int db; 6 } c[maxn]; 7 bool cmp(point a,point b){ 8 return a.da<b.da; 9 } 10 int main() { 11 int t; 12 scanf("%d",&t); 13 while(t--) { 14 int x1,y1,x2,y2; 15 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 16 int n; 17 scanf("%d",&n); 18 for(int i=0;i<n;++i){ 19 scanf("%d%d",&c[i].x,&c[i].y); 20 int x=c[i].x,y=c[i].y; 21 c[i].da=(x-x1)*(x-x1)+(y-y1)*(y-y1); 22 c[i].db=(x-x2)*(x-x2)+(y-y2)*(y-y2); 23 } 24 sort(c,c+n,cmp); 25 int min_d = c[n-1].da; 26 int tmp=0; 27 for(int i=n-2;i>=0;--i){ 28 tmp=max(tmp,c[i+1].db); 29 min_d=min(min_d,tmp+c[i].da); 30 } 31 tmp=max(tmp,c[0].db); 32 min_d=min(min_d,tmp); 33 printf("%d\n",min_d); 34 } 35 return 0; 36 }