D - Cat and Mice Kattis - catandmice (状压+二分)
题目链接:
https://cn.vjudge.net/problem/Kattis-catandmice
题目大意:
自己翻译,懒得写
具体思路:
二分枚举最佳速度,然后状压dp判断是否合理。
AC代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define inf 0x3f3f3f3f 5 #define LL_inf (1ll << 60) 6 const int maxn = 2e5 + 100; 7 const int mod = 1e9 + 7; 8 const double eps = 1e-5; 9 struct node 10 { 11 double x, y, t; 12 node() {} 13 node(double t1, double t2, double t3) 14 { 15 x = t1; 16 y = t2; 17 t = t3; 18 } 19 } q[maxn]; 20 double dp[34000][20]; 21 char str[10]; 22 int n; 23 double dis(double x1, double y1, double x2, double y2) 24 { 25 return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); 26 } 27 int cnt[maxn]; 28 int cal(int t) 29 { 30 int ans = 0; 31 for (int i = 0; i < 16; i++) 32 { 33 ans += ((t & (1 << i)) > 0 ? 1 : 0); 34 } 35 return ans; 36 } 37 void init() 38 { 39 int maxstate = (1 << n) - 1; 40 for (int i = 0; i <= maxstate; i++) 41 { 42 cnt[i] = cal(i); 43 } 44 } 45 double qsm(double t1, int t2) 46 { 47 double ans = 1.0; 48 while (t2) 49 { 50 if (t2 & 1) 51 ans = ans * t1; 52 t2 >>= 1; 53 t1 = t1 * t1; 54 } 55 return ans; 56 } 57 bool check(double t, double lv) 58 { 59 for(int i=0; i<(1<<n); i++) 60 for(int j=0; j<n; j++) 61 dp[i][j]=inf; 62 int maxstate = (1 << n) - 1; 63 for (int i = 0; i < n; i++) 64 { 65 if (dis(q[i].x, q[i].y, 0.0, 0.0) / t <= q[i].t) 66 dp[(1 << i)][i] = dis(q[i].x, q[i].y, 0.0, 0.0) / t; 67 } 68 for (int i = 1; i <= maxstate; i++) 69 { 70 for (int j = 0; j < n; j++) 71 { 72 for (int k = 0; k < n; k++) 73 { // 这里加判断(i&(1<<k)),时间差4倍多,, 74 if ((i & (1 << j)) &&((i & (1 <<k))==0) &&(dis(q[j].x, q[j].y, q[k].x, q[k].y) / (t * qsm(lv, cnt[i])) + dp[i][j] <= q[k].t)) 75 { 76 dp[i | (1 << k)][k] = 77 min(dp[i | (1 << k)][k], 78 dis(q[j].x, q[j].y, q[k].x, q[k].y) / (t * qsm(lv, cnt[i] )) + dp[i][j]); 79 } 80 } 81 } 82 } 83 for (int i = 0; i < n; i++) 84 { 85 if (dp[maxstate][i] <= q[i].t) 86 return true; 87 } 88 return false; 89 } 90 int main() 91 { 92 scanf("%d", &n); 93 init(); 94 for (int i = 0; i < n; i++) 95 { 96 scanf("%lf %lf %lf", &q[i].x, &q[i].y, &q[i].t); 97 } 98 double lv; 99 cin>>lv; 100 double l = 0, r = 1e9; 101 double ans = 0; 102 while (r - l >=eps) 103 { 104 double mid = (l + r) / 2.0 ; 105 if (check(mid, lv)) 106 { 107 ans=mid; 108 r = mid; 109 } 110 else 111 l = mid; 112 } 113 printf("%.3f\n", ans); 114 return 0; 115 }