二分,最小化最大值(分块)
题意:
给定一个字符串和数字k,表示可以最多将这个字符串分成k行line[1],line[2]......line[k],分割的位置只能是'-'和空格的位置,问如何分割可以使max_strlen( line[1~k] )最短。
solution:
典型的最大值最小问题,预处理出每个分割点的位置,及其子串的长度,二分最大值即可。
1 /************************************************************************* 2 > File Name: a.cpp 3 > Author: QWX 4 > Mail: 5 > Created Time: 2018/11/2 10:35:53 6 ************************************************************************/ 7 8 9 //{{{ #include 10 #include<iostream> 11 #include<cstdio> 12 #include<algorithm> 13 #include<vector> 14 #include<cmath> 15 #include<queue> 16 #include<map> 17 #include<set> 18 #include<string> 19 #include<cstring> 20 #include<complex> 21 #include<cassert> 22 //#include<bits/stdc++.h> 23 #define vi vector<int> 24 #define pii pair<int,int> 25 #define mp make_pair 26 #define pb push_back 27 #define fi first 28 #define se second 29 #define pw(x) (1ll << (x)) 30 #define sz(x) ((int)(x).size()) 31 #define all(x) (x).begin(),(x).end() 32 #define rep(i,l,r) for(int i=(l);i<(r);i++) 33 #define per(i,r,l) for(int i=(r);i>=(l);i--) 34 #define FOR(i,l,r) for(int i=(l);i<=(r);i++) 35 #define cl(a,b) memset(a,b,sizeof(a)) 36 #define fastio ios::sync_with_stdio(false);cin.tie(0); 37 #define lson l , mid , ls 38 #define rson mid + 1 , r , rs 39 #define INF 0x3f3f3f3f 40 #define LINF 0x3f3f3f3f3f3f3f3f 41 #define ll long long 42 #define ull unsigned long long 43 #define dd(x) cout << #x << " = " << (x) << "," 44 #define de(x) cout << #x << " = " << (x) << "\n" 45 #define endl "\n" 46 using namespace std; 47 //}}} 48 49 int n; 50 vi v; 51 bool check(int mx) 52 { 53 int res=0; 54 int cnt=1; 55 for(auto t:v){ 56 res+=t; 57 if(res>mx)res=t,cnt++; 58 // dd(cnt),de(res); 59 } 60 // de(cnt); 61 return cnt<=n; 62 } 63 64 int main() 65 { 66 cin>>n; 67 getchar(); 68 string s; 69 getline(cin,s); 70 // de(s); 71 int mx=0,cnt=0; 72 for(auto t:s){ 73 // de(t); 74 cnt++; 75 if(t==' '||t=='-')mx=max(mx,cnt),v.pb(cnt),cnt=0; 76 } 77 mx=max(mx,cnt);v.pb(cnt); 78 // de(mx); 79 // de(sz(v)); 80 // for(auto t:v)de(t); 81 int l=mx,r=sz(s),ans=0; 82 // de(r); 83 // de(check(11)); 84 while(l<=r){ 85 int mid=l+r>>1; 86 if(check(mid))r=mid-1,ans=mid; 87 else l=mid+1; 88 // de(ans); 89 } 90 cout<<ans<<endl; 91 return 0; 92 }