Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
dp,几乎1A,atan函数为啥一定要用double,搞了一次CE,4776K 454ms(poj的编译器真是个吭)#include <iostream> #include <stdio.h> #include <cmath> #include <algorithm> using namespace std; int B, N; const double PI = 3.141592654; const double INF_D = 1e10; struct pt{ int x,y; }points[110]; pt origin; double K[110]; double dp[60][110][110]; double k(pt p){ int x = p.x, y = p.y; if(y == 0 && x > 0) return 0; if(y == 0) return PI; if(x == 0 && y > 0) return 0.5*PI; if(x == 0) return 1.5*PI; double ans = atan2(y+0.0,x+0.0); if(ans < 0) ans += 2*PI; return ans; } bool compare(int p1, int p2){ return K[p1] < K[p2]; } int sign(pt p1, pt p2, pt p3){ int get = p1.x*p2.y + p2.x*p3.y + p3.x*p1.y - p1.y*p2.x - p2.y*p3.x - p3.y*p1.x; if(get > 0) return 1; return -1; } int intvLen(int a, int b){ if(a <= b) return b-a+1; else return b+(N-1)-a+1; } bool neimian(pt p1, pt p2, pt p3){ int sign1 = sign(p1, p2, origin); int sign2 = sign(p1, p2, p3); if(sign1 * sign2 == 1) return 0; return 1; } double mianji(pt p1, pt p2){ return 0.5 * abs(0.0 + p1.x*p2.y-p1.y*p2.x); } int main() { origin.x = 0, origin.y = 0; while(1){ scanf("%d%d", &B, &N); if(B == 0 && N == 0) return B+N; int x,y; scanf("%d%d", &x, &y); for(int i = 0; i < N-1; i++){ int X, Y; scanf("%d%d", &X, &Y); X -= x, Y -= y; points[i].x = X, points[i].y = Y; } int order[110]; for(int i = 0; i < N-1; i++) order[i] = i; for(int i = 0; i < N-1; i++) K[i] = k(points[i]); sort(order, order+N-1, compare); double mj[110][110]; for(int startP = 0; startP < N-1; startP++){ int dygd = (startP + 1)%(N-1); int dians[110], dianNum = 2; dians[0] = startP, dians[1] = dygd; int curP; mj[startP][dygd] = 0.5*abs(0.0+points[order[startP]].x*points[order[dygd]].y-points[order[startP]].y*points[order[dygd]].x); for(curP = (dygd+1)%(N-1); ; curP = (curP+1)%(N-1)){ double cha = K[order[curP]] - K[order[startP]]; if(cha > PI+1e-8 || (cha < 0 && cha > -PI+1e-8)){ break; } if(!neimian(points[order[dians[dianNum-2]]], points[order[dians[dianNum-1]]], points[order[curP]])){ dians[dianNum] = curP; mj[startP][curP] = mj[startP][dians[dianNum-1]] + mianji(points[order[dians[dianNum-1]]], points[order[curP]]); dianNum++; } else{ //二分 int l = 0, u = dianNum - 2; while(l != u){ int m = (l+u)/2; if(neimian(points[order[dians[m]]], points[order[dians[m+1]]], points[order[curP]])){ u = m; } else{ l = m+1; } } dians[l+1] = curP; mj[startP][curP] = mj[startP][dians[l]] + mianji(points[order[dians[l]]], points[order[curP]]); dianNum = l+2; } } for(int bknP = curP; bknP != startP; bknP = (bknP+1)%(N-1)){ mj[startP][bknP] = INF_D; } } for(int i = 0; i < N-1; i++){ for(int j = 0; j < N-1; j++){ if(i == j) continue; dp[1][i][j] = mj[i][j]; } } for(int b = 2; b <= B; b++){ for(int i = 0; i < N-1; i++){ for(int j = 0; j < N-1; j++){ int intvL = intvLen(i, j); if(i == j || intvL < 2*b || (b==B && intvL != N-1)) continue; double mn = INF_D; for(int iL = 2; iL <= intvL - 2*b + 2; iL++){ int end = (i+iL-1)%(N-1), stt = (end+1)%(N-1); double tmp = mj[i][end] + dp[b-1][stt][j]; if(tmp < mn) mn = tmp; } dp[b][i][j] = mn; } } } double ans = INF_D; for(int i = 0; i < N-1; i++){ double tempAns = dp[B][i][(i+N-2)%(N-1)]; if(tempAns < ans) ans = tempAns; } printf("%.2lf\n", ans); } return 0; } Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator