P2678 跳石头 (二分答案)
题目链接:P2678
解题思路:
如果可行解为单调,则可以用二分答案找到最终答案,对于选到的答案,去验证是否正确,最后确定所需解。
AC代码:
1 #include <cstdio> 2 #include <iostream> 3 #define ll long long 4 using namespace std; 5 ll l,n,m,d[50010],t[50010]; 6 bool judge(ll x) // 判断该解是否合适 7 { 8 ll s = 0; 9 for(ll i = 1; i <= n; i++) t[i] = d[i]; 10 for(ll i = 1; i <= n; i++) 11 { 12 if(t[i]-t[i-1] < x) 13 { 14 t[i] = t[i-1]; // 搬石头时可以将前一个值复制到现在的值,实现O(1)的操作 15 s++; 16 } 17 } 18 if(s > m) return false; 19 else return true; 20 } 21 ll bfind(ll l, ll r) 22 { 23 ll mid; 24 while(r-l > 1) // r-l = 1时,有可能会死循环 25 { 26 mid = (r-l)/2+l; 27 if(judge(mid)) l = mid; // judge判断是否正确,然后左右区间调整 28 else r = mid-1; 29 } 30 if(judge(r)) return r; 31 else return l; 32 } 33 int main() 34 { 35 cin >> l >> n >> m; 36 for(ll i = 1; i <= n; i++) cin >> d[i]; 37 cout << bfind(1,l); 38 return 0; 39 }

浙公网安备 33010602011771号