廊桥分配
1.错误想法:让当前飞机停到右端点最小的廊桥,但是当两个区间右端点都小于当前飞机左端点,选择最小的么?
显然不是,应该选择序号最小的廊桥,这样不影响下一个飞机继续放置(左端点从小打到排序的)。这样,当只能有i个廊桥(枚举国内廊桥)的时候,也是可以取得最大值的。最后前缀和。错误代码附后。
2.正确解法:换一个思路。如果尽可能先让第一个廊桥占满,可以让当前廊桥选择后序飞机,则二分找到第一比当前廊桥右端点大的飞机。再继续找。
#include <stdc++.h>
using namespace std;
typedef pair<int, int > PII;
const int N = 100005;
int n, m1, m2,suma[N],sumb[N];
std::set<std::pair<int, int> > a, b;
inline void Work(set<PII> &st, int sum[]) {
for (int i = 1; i <= n; ++i) {
vector<PII> del;
sum[i] += sum[i - 1];
set<PII>::iterator it = st.begin();
while(it != st.end()){
++sum[i];
st.erase(it);
it = st.lower_bound(make_pair(it->second, 0));
}
}
}
int main() {
scanf("%d%d%d", &n, &m1, &m2);
for (int i = 1; i <= m1; ++i) {
int l, r; scanf("%d%d", &l, &r);
a.insert(make_pair(l, r));
}
for (int i = 1; i <= m2; ++i) {
int l, r; scanf("%d%d", &l, &r);
b.insert(make_pair(l, r));
}
Work(a, suma);
Work(b, sumb);
int ans = 0;
for (int i = 0; i <= n; ++i)
ans = max(ans, suma[i] + sumb[n - i]);
printf("%d\n", ans);
return 0;
}
/*
10 100 100
13 956
463 517
281 586
540 636
103 573
890 893
45 639
23 320
305 667
556 775
630 716
529 1000
173 741
174 276
6 51
724 763
291 663
334 401
250 511
373 710
467 696
265 449
317 432
92 955
14 707
411 860
603 643
251 874
190 705
9 310
285 539
408 615
861 951
319 413
368 714
264 688
271 670
43 353
792 872
240 770
2 348
325 687
253 750
464 509
543 704
963 989
4 998
148 198
698 899
532 929
50 149
41 168
255 802
246 768
252 656
237 363
146 151
70 119
364 477
578 936
771 809
551 952
434 903
535 609
607 948
446 828
311 313
758 937
62 122
11 614
909 947
898 918
201 862
178 421
176 269
38 420
513 754
67 175
254 360
740 912
134 225
141 922
87 111
553 751
234 331
329 452
783 810
55 162
136 322
762 977
387 856
314 815
653 935
442 817
36 212
362 949
30 637
737 832
53 999
159 531
431 796
215 385
63 718
395 647
289 298
488 545
7 438
596 876
611 628
1 699
61 278
286 367
196 220
25 645
772 914
323 328
537 984
465 501
445 672
19 709
581 953
126 550
88 326
969 994
184 245
247 346
284 660
339 407
338 584
599 703
199 224
959 974
365 826
496 519
34 980
73 835
624 712
171 209
419 466
40 934
189 476
559 646
577 804
816 821
376 435
392 572
793 852
306 495
457 593
206 340
127 512
161 260
273 855
669 897
95 892
824 849
72 524
48 86
576 585
5 927
487 561
676 819
107 734
143 781
642 674
28 129
514 695
137 294
94 978
390 957
147 261
482 652
12 403
571 941
399 961
681 789
83 181
230 853
564 764
542 732
394 654
283 827
106 790
486 993
56 480
105 931
910 991
379 469
479 689
104 414
612 800
798 850
785 799
185 337
15 973
791 807
610 728
396 923
277 884
69 79
32
*/
错误代码:
#include<stdc++.h>//bits/
using namespace std;
int k,c[100005],cnt=1,suma[100005], sumb[10005],mx;
struct Node{
int l,r;
bool operator<(const Node &A)const{
return l < A.l;
}
}a[100005];
struct Data{
int l, r, id;
bool operator<(const Data &B)const{
return r > B.r;
}
}t,b[100005];
priority_queue<Data> q;
void mem(){
cnt = 1;
memset(a, 0, sizeof a);
memset(b, 0, sizeof b);
memset(c, 0, sizeof c);
while(!q.empty()) q.pop();
}
void f(int n, int sum[]){
for(int i = 1; i <= n; i++) cin>>a[i].l>>a[i].r;
sort(a+1,a+n+1);
for(int i = 1; i <= n; i++) b[i].l = a[i].l, b[i].r = a[i].r;
b[1].id = 1; q.push(b[1]); c[1]++;
for(int i = 2; i <= n; i++){
if(!q.empty()) t = q.top();
if(b[i].l > t.r){
c[t.id]++;
if(!q.empty()) q.pop();
b[i].id = t.id; q.push(b[i]);
}
else{
cnt++;
c[cnt]++;
b[i].id = cnt; q.push(b[i]);
}
}
// sort(c+1, c+cnt+1, greater<int>());
for(int i = 1; i <= n; i++)
sum[i] = sum[i-1] + c[i];
}
int main(){
int n,m; cin>>k>>n>>m;
f(n, suma);
cout<<endl;
cout<<"cnt1: "<<cnt<<endl;
cout<<"suma:"<<endl;
for(int i = 1; i <= cnt; i++)
cout<<suma[i]<<" ";
cout<<endl;
mem();
f(m, sumb);
cout<<endl;
cout<<"cnt2: "<<cnt<<endl;
cout<<"sumb:"<<endl;
for(int i = 1; i <= cnt; i++)
cout<<sumb[i]<<" ";
cout<<endl;
for(int i = 0; i <= k; i++){
if(suma[i] + sumb[k-i] > mx){
mx = suma[i] + sumb[k-i];
}
}
cout<<mx<<endl;
return 0;
}
/*
- - - -
- -
-
- - -
- -
-
2 5 10
36 275
131 223
222 308
40 60
50 70
61 80
71 90
81 100
167 240
101 120
166 220
46 194
130 150
186 243
153 170
7
*/