二分之ans学习
思路:
就是二分答案,二分答案好似一元方程求解,check的mid就是假设的x
这里,假设长度x,如果N条绳子除以x剩余k条绳子,那么答案就是x
小知识,if check中添加一个ans=mid,答案直接输出ans即可
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+9;
int a[N];
int n,k;
bool check(int len){
int get=0;
for(int i=1;i<=n;i++){
get+=a[i]/len;
}
if(get>=k){
return 1;
}else return 0;
}
void moyuhualuo(){
cin>>n>>k;
int r=-0x3f3f3f3f;
for(int i=1;i<=n;i++){
cin>>a[i];
r=max(r,a[i]);
}
int mid,l=0;
int ans;
while(l<r){
mid=l+r>>1;
if(check(mid)){
l=mid+1;
ans=mid;
}else r=mid;
}
cout<<ans;
}
int main( )
{
cin.tie(nullptr)->sync_with_stdio(false);
moyuhualuo();
return 0;
}
看一看时间复杂度:
二分时间复杂度:n/2,n/4,n/8…(n/2)^k,时间复杂度是Olog2(n) -> Ologn
本题时间复杂度:n+logn*n -> O(nlogn)
二分答案+公式推导
推导如下:
#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;
typedef long long ll;
const int N = 2e5 + 9;
int v[N], u[N];
double t[N];
int n, m;
bool cmp(int a, int b) {
return a > b;
}
bool check(double x) {
double sum = 0;
for (int i = 1; i <= n; i++) {
t[i] = v[i] - x * u[i];
} sort(t + 1, t + 1 + n, cmp);
for (int i = 1; i <= m; i++) {
sum += t[i];
}
if (sum > 0) {
return 1;
}
else return 0;
}
void moyuhualuo() {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> v[i];
for (int i = 1; i <= n; i++) cin >> u[i];
double l = 0, r = 1050;
double mid;
while (r - l > 1e-5) {
mid = (l + r) * 1.0 / 2;
// cout<<mid<<endl;
if (check(mid)) {
l = mid;
}
else {
r = mid;
}
}
cout << fixed << setprecision(3) << l;
}
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
moyuhualuo();
return 0;
}
时间复杂度:n+n+log(n)(n+nlog(n)+n) -> nlog^2(n)
二分时间复杂度按照 == logn==
sort 时间复杂度按照 ==nlogn ==
今日无事,勾栏听曲 ^ _ ^