Talk about 01 backpack and dichotomy

title: "01 backpack and dichotomy"
author: Sun-Wind
date: October 21, 2021

Background of this post: Recently, the blogger was practicing the problem of 01 knapsack and found that a problem combined 01 knapsack and bisection algorithm, which greatly inspired Ben konjak. I hereby come to water to share

#Knowledge reserve
##01 Backpack
The classical 01 knapsack problem is given a certain number of items and a limited size knapsack, each item has a certain value, and it is required that how many value items can be loaded at most without exceeding the knapsack capacity

We first give the generalized two-dimensional knapsack equation dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i]] + v[i])

  • dp[i][j] means the maximum value when the backpack capacity of the i-th item is j when the first i-1 item has been considered
  • w[i] represents the weight of the ith article, and v[i] represents the value of the ith article (val)
  • The essence of this recursive equation is to divide the knapsack into many small parts from 0 to knapsack capacity, which can take into account all cases
  • The meaning of recurrence equation is that the maximum value when the i-th article capacity is j is the maximum value when the i-1 article capacity is j and the maximum value when the i-1 article capacity is j-w[i] plus the value of the i-th article (in fact, the i-th article is selected and the i-th article is not selected)

We can think about recursive equations like this

If there are 3 items, the capacity of the backpack is 8, and the weight and value of the items are 3, 6, 4, 7, 5 and 8 respectively
When we cycle to the second item is dp[2][8], we take both items into account and the value is 13
However, when we cycle to the third item, the capacity of the backpack is not enough, but it is still a case because we put this item into the backpack
In order not to miss the solution, dp[3][8] = max(dp[2][8],dp[2][8-5] + 8)
We divide the knapsack here. Obviously, when the knapsack capacity is 3, we put item 1 into the knapsack. It is the optimal solution when the knapsack capacity is 8

Other cases can also be analogized, so that we can not only consider each case, but also find the optimal solution
The core code is as follows

 for(i = 1; i <= m; ++i)//Enumeration number
        for(j = 1; j <= n; ++j)//Enumeration capacity
    {
        if(w[i] <= j)
        dp[i][j] = max(dp[i - 1][j],dp[i - 1][j - w[i]] + v[i]);
        else
        dp[i][j] = dp[i - 1][j];
    }

OK, I'll give you five minutes to think before we continue

  • 1
  • 2
  • 3
  • 4
  • 5

###01 optimization of backpack space
Next, we consider optimizing the two-dimensional array of 01 knapsack from two-dimensional to one-dimensional
Core DP [i] [J] ---- > DP [J]
dp[j] = max(dp[j],dp[j-w[i]] + v[i])

  • The optimized 1-dimensional array represents the maximum value that can be obtained when the backpack capacity is j
  • w[i],v[i] is the same as the above example
  • The recurrence here is from the maximum value of knapsack capacity J in the previous state (i.e. only considering the first i-1 items) to this state (starting to consider the maximum value when the capacity of the i-th item is j)
    According to the code of two-dimensional array, we can bring it naturally
for(i = 1; i <= m; ++i)
      for(j = 1; j <= n; j--)
    {
        if(w[i] <= j)
        dp[j] = max(dp[j],dp[j - w[i]] + v[i]);//The previous status is dp[j] stored here
    }

Well, yes, most of them are correct, but one more thing to pay attention to -- cycle order

Try to think about the positive order cycle. We may face the problem that if there was an item with the weight of K in the backpack, when j = k, we will face whether to put this special item into the backpack,
When j is 2k, we will face the same choice
If we find that putting this item into the backpack is more valuable in both choices, what will happen next?
Obviously, we put an item twice, but an item can only be put once, which is inconsistent with the meaning of the title

Therefore, we need to reverse the cycle order. The code is as follows:

    for(int i = 0;i < n;i ++){
        int v, w;
        cin >> v >> w;
        for(int j = V;j >= v;j --)//Obviously, if J < V, you don't need to put this item in, so you don't need to update the cycle
            dp[j] = max(dp[j], dp[j - v] + w);//Both states in max are the previous state
    }
    cout << dp[V];

That's the end of the explanation of 01 backpack. 01 backpack has many extensions, such as multiple backpacks, complete backpacks, etc. we won't discuss these for the time being

Next, let's look at the others
##Dichotomy
All numbers on the left of the critical point meet or do not meet a certain condition, and the numbers on the right do not meet or meet a certain condition (that is, the opposite of the previous one)

  • As the name suggests, dichotomy is constantly looking for the middle value and constantly approaching the answer we want
  • A general template is given below (the specific may vary according to the requirements of the topic)
 while(l < r)
        {
            int mid = l + r >> 1;
            if(check(mid))//Check whether the intermediate value meets the requirements
                l = mid + 1;
            else
                r = mid;
        }

Here is an example to help us understand
Given a set of numbers 1 2 3 4 5, a total of 6 numbers, it is required to find the first number greater than or equal to 3
Obviously, this array satisfies our preconditions, some less than 3 and some not less than 3.
According to the properties of bisection algorithm, we can find this critical point in theory

Our answer is selected from 1 to 6 (here refers to the number of each number), so the left boundary of l is 1 and the right boundary of r is 6.
The first mid is 3, and the third number meets the requirements. However, since we need to find the first number, this number may or may not be the first, so the right boundary should become mid; then continue to judge until we find the critical value we want

Well, now that we have a certain knowledge reserve, let's take an example of the combination of 01 backpack and dichotomy:
##Examples
This question comes from Luogu P2370 (if you understand it, you can go to ac by yourself)
###Title Description
You borrowed this high-end USB flash disk from yyy2015c01 and copied some important information, but you found some problems with this USB flash disk:

  • The transmission interface of this U SB flash disk is very small. It can only transfer files with a size of no more than L.
  • The capacity of this U SB flash drive is very small. It can only hold no more than S files.
    But you have a lot of data to back up. You can only back up some of them.

In order to select which files to back up, you set a value Vi for all files. The total value of the files you want to back up is not less than p.

But soon you find that this is impossible, because the transmission interface of yyy2015c01 is too small. You have to spend money to buy a larger interface (a larger interface means that you can transmit larger files, but it will cost more money to buy it).

Note: your files cannot be divided (you can only transfer a whole file and store it in the U SB flash disk),

The total size of the files you put on the USB flash disk cannot exceed the capacity of the USB flash disk.

Now the question comes: you want to know how much interface is required when the sum of the file values on the U SB flash disk is not less than p.

###Input format
In line 1, the three positive integers n, P and s respectively represent the total number of files, the desired minimum value p and the hard disk size.

Next n lines, two positive integers Wi,Vi for each line
Represents the size and value of the ith file.
###Output format
Output a positive integer indicating the minimum required interface size.

If there is No Solution, output No Solution!.
###Input

3 3 5
2 2
1 2
3 2

###Output
2
###Input

2 3 505
1 2
500 1

###Output

500

###Input

3 3 2
2 2
1 2
3 2

###Output
No Solution!
###Input

4 5 6
5 1
5 2
5 3
1 1

###Output
No Solution!

###Train of thought analysis
Through the key words in the title, such as limiting the size, value and other factors, we can preliminarily judge that it may be a 01 knapsack problem. However, another factor in the title is that the value obtained must exceed the value given, and we have to find the smallest interface
This information gives us a lot of confusion

  • First of all, we need to determine what the information represented by the 01 backpack is
    Is the smallest interface and the greatest value???

Each time we select a selection method, the size of the interface obtained is the maximum size of all the interfaces in the backpack. Then we have to select all the qualified selection methods and find the smallest one from these interfaces. If we consider representing the smallest interface, it is obviously very difficult to maintain, and because the value given by the topic is very large, it is difficult to store it in an array

  • If it represents the greatest value, what should we do?
    To illustrate, in the title, we can conclude that this is a maximum minimum problem, and this is a very classic binary keyword.

We can know all ports from the initial input, and the port with the correct answer must be between this interval. However, the ports given in the title are not necessarily continuous. For example, three ports 80, 90100; We only know that the answer is one of the three ports, but not 81, 82 and so on; Therefore, it is correct for us to set the binary element. The answer is less than or equal to the port size we want.
In this way, it is obvious that a critical point will appear between the two partitions, and the left side of the critical point does not meet the requirement of dichotomy, and the right side of the critical point meets the requirement of dichotomy
So we just need to dichotomy this interval to approach the answer

 while (minn < maxx)
    {
        midd = minn + maxx >> 1;
        if (dp(midd) >= m)//For details of dp function, please continue to analyze
            maxx = midd;
        else
            minn = midd + 1;//minn and maxx are left and right boundaries respectively
    }

Therefore, we need to make a 01 backpack for this port every time we judge. If there is a port larger than it, we must not select it (because if it is selected, the largest port will change),

int dp(int x)
{
    for(int i = 0; i <= s; ++i)
        Matrix[i] = 0;
    for(int i = 1; i <= n; ++i)
    {
        if (x != -1 && x < w[i])//If it is much larger than him, it will not be considered. Here, a special case of - 1 is to determine whether there is a solution. The case of - 1 is to find the maximum value of the backpack without restrictions
            continue;
        for (int j = s; j >= w[i]; --j)
            Matrix[j] = max(Matrix[j], Matrix[j - w[i]] + v[i]);
    }
    return Matrix[s];
}

Less than or equal to it can be put into the backpack. As long as there is a solution that can make the value of the selected scheme greater than the value given by the topic, it is obvious that this port meets the requirements and the right section moves forward, (if we know that the port less than or equal to X can gather the value that meets the meaning of the question, the number greater than x will certainly include the scheme of X. therefore, the value calculated by the following 01 knapsack can only be higher than it.)

  • We have to solve the problem, and the whole idea is formed
    The complete code is attached below
#include <iostream>
#include <utility>
using namespace std;
typedef long long ll;
#define fi(a, b) for (int i = a; i <= b; ++i)
#define fr(a, b) for (int i = a; i >= b; --i)
using pii = pair<int, int>;
const int N = 1e3 + 5;
const int M = 1e5 + 5;
int w[N], v[N];
int n, m, s;
int Matrix[M];
//#define DEBUG
int dp(int x)
{
    fi(0, s)
        Matrix[i] = 0;
    fi(1, n)
    {
        if (x != -1 && x < w[i])
            continue;
        for (int j = s; j >= w[i]; --j)
            Matrix[j] = max(Matrix[j], Matrix[j - w[i]] + v[i]);
    }
    return Matrix[s];
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
#ifdef DEBUG
    //freopen(D:\in.txt,r,stdin);
#endif
    cin >> n >> m >> s;
    int minn = 0x3f3f3f3f;
    int maxx = -minn;
    fi(1, n)
    {
        cin >> w[i] >> v[i];
        minn = min(minn, w[i]);
        maxx = max(maxx, w[i]);
    }
    int midd;
    while (minn < maxx)
    {
        midd = minn + maxx >> 1;
        if (dp(midd) >= m)
            maxx = midd;
        else
            minn = midd + 1;
    }
    if (dp(-1) < m)
        cout << "No Solution!" << endl;
    else
    {
        cout << minn << endl;
    }
    return 0;
}

By the way, post some hack examples obtained by bloggers (previously, you could only cheat 70 points with a two-dimensional backpack)
input

13 62 124
20 13
20 19
20 13
34 13
49 133
43 1
20 22
20 30
36 30
36 4
42 13
37 11
44 1
37 16
21 10
36 19
49 27
27 5
24 11
23 13
50 25
44 27
37 12
48 1

output
20
input

840 269 909
108 240
978 297
474 362
999 994
121 72
704 261
300 285
281 239
882 563
486 972
933 295
131 280
741 374
457 78
44 15
45 12
870 749
331 843
53 61
241 584
76 195
522 955
910 695
877 917
737 228
256 443
357 4
229 98
487 648
352 416
363 559
136 205
880 634
508 874
61 136
730 78
861 203
420 919
692 605
60 96
789 809
670 301
242 923
994 586
849 700
750 483
461 615
738 944
474 897
610 953
759 303
260 579
681 347
302 741
754 119
383 253
860 251
484 340
451 93
176 592
960 711
817 462
477 429
564 598
748 728
684 889
987 590
927 826
881 759
544 339
581 728
263 535
662 217
878 823
778 378
442 246
101 44
307 217
115 349
182 68
980 132
895 300
564 407
445 147
354 447
705 595
171 58
674 617
589 594
758 366
632 779
130 170
153 478
547 37
642 860
129 164
790 364
74 168
565 997
939 220
478 651
135 80
872 671
253 421
664 473
109 136
491 675
120 106
225 464
660 403
491 428
509 462
640 847
920 112
496 168
73 176
127 204
567 341
570 578
393 156
873 286
647 627
193 282
1000 154
648 910
465 868
837 54
629 488
940 953
264 740
417 483
159 417
960 748
656 146
200 253
611 125
61 16
858 559
866 102
566 6
720 357
973 364
725 259
883 461
234 259
520 780
176 642
409 352
31 0
926 231
710 606
48 88
202 427
566 956
607 666
125 388
129 85
535 907
172 707
921 456
971 336
817 484
373 157
597 923
454 918
786 754
63 31
980 719
257 132
331 665
952 522
644 88
506 388
517 446
339 651
571 770
751 629
866 914
390 953
676 441
194 379
203 284
55 38
142 174
261 89
617 332
321 11
156 490
699 994
109 316
528 210
569 416
391 761
416 759
400 441
435 56
272 401
531 746
288 381
509 987
376 34
395 274
589 728
730 462
677 494
698 854
916 299
950 672
542 231
792 770
680 355
918 456
898 517
953 336
959 531
90 210
152 436
281 665
265 143
535 742
721 651
411 365
403 880
924 614
358 971
495 814
261 442
983 910
988 325
200 372
310 898
304 412
212 25
1000 831
527 302
243 247
455 566
218 520
576 800
305 580
481 143
735 553
933 293
276 621
92 22
573 843
156 183
533 156
66 111
420 565
777 52
911 162
210 692
721 516
761 407
381 259
903 361
901 663
990 467
848 231
881 5
585 870
949 501
707 607
230 18
183 544
142 405
637 804
229 103
587 1
204 49
994 100
456 854
598 165
529 564
217 174
981 578
244 147
710 629
184 751
713 779
129 316
164 157
758 766
634 456
136 27
83 133
538 559
363 691
476 566
739 743
642 912
446 988
746 949
924 833
344 634
811 197
594 859
930 371
335 66
889 154
81 71
658 843
692 648
672 21
689 975
485 694
270 244
56 10
553 209
414 924
565 781
908 788
702 423
967 429
915 40
183 468
112 95
591 793
255 392
891 245
757 69
688 679
643 446
342 715
779 573
458 937
192 150
75 118
727 924
542 282
177 115
709 524
769 105
47 17
319 407
455 726
956 455
720 405
969 880
842 650
473 583
755 389
848 329
972 961
602 27
854 182
885 746
362 161
347 568
675 926
464 553
555 675
36 24
901 141
816 763
982 834
341 481
94 87
528 510
747 727
576 393
468 918
285 452
993 764
87 131
951 170
485 984
62 85
881 844
74 131
529 3
669 498
796 861
535 798
527 337
299 939
802 143
863 398
74 118
190 191
236 881
828 637
417 258
790 533
739 291
89 122
355 52
272 209
84 132
816 342
871 560
158 283
173 508
229 936
577 899
242 631
389 848
165 152
486 182
488 260
750 574
378 546
576 397
698 109
425 864
62 0
505 443
836 364
929 2
162 598
288 874
278 329
324 728
813 644
472 779
196 408
708 291
821 657
202 324
178 3
98 256
382 660
793 849
603 297
843 200
429 403
216 396
902 852
508 343
687 528
68 91
906 84
797 714
347 624
915 217
109 297
845 281
129 256
546 77
856 273
173 580
863 539
297 327
904 537
648 449
862 791
133 264
285 196
679 273
869 539
545 205
817 787
767 222
929 499
989 930
789 576
969 508
593 624
504 326
408 172
888 778
231 69
248 509
393 213
366 616
965 308
536 319
100 87
846 838
304 704
226 442
895 491
756 338
458 494
150 17
295 496
962 671
59 98
738 962
366 461
231 69
762 280
287 361
355 724
592 344
861 289
339 988
600 970
294 115
806 951
412 284
536 466
630 962
669 965
71 205
402 105
523 651
697 912
543 528
927 189
742 580
185 256
445 669
938 902
979 884
814 149
922 533
668 425
983 413
648 954
883 547
999 484
991 160
475 906
482 132
468 331
82 231
789 22
439 547
238 325
221 778
138 517
272 380
292 44
622 832
775 316
425 385
250 231
411 316
795 589
868 499
409 616
46 54
299 905
85 252
387 282
518 566
488 518
416 570
328 249
924 154
542 117
721 867
626 99
123 61
577 826
173 14
721 881
473 679
168 438
544 858
126 119
246 87
915 52
562 189
787 126
456 210
361 77
810 320
594 537
955 16
375 601
53 107
777 139
569 835
179 436
506 80
96 323
119 220
331 540
898 11
492 413
359 798
214 16
960 366
179 62
857 448
461 867
562 923
511 66
952 280
743 742
640 361
807 936
981 858
164 521
374 841
699 149
174 161
484 231
644 736
908 23
558 35
129 404
758 666
927 210
533 958
507 375
851 338
571 6
432 256
205 318
317 434
540 236
219 722
475 113
264 898
30 0
306 235
634 797
469 398
86 243
610 914
650 0
915 376
151 422
74 84
970 12
43 62
966 115
693 533
904 495
649 123
469 449
702 119
529 970
92 261
55 89
240 345
226 800
746 907
970 167
561 202
573 423
356 116
456 17
806 962
267 577
113 136
463 0
903 767
355 527
95 247
222 44
459 658
714 571
101 80
364 895
897 468
364 169
934 952
190 495
165 468
284 946
647 390
643 250
52 57
457 969
475 462
769 501
304 957
288 600
679 364
225 804
600 208
233 241
342 13
110 261
720 518
225 752
585 469
143 242
357 532
297 341
942 846
310 56
904 822
482 689
773 100
446 350
276 178
384 717
937 581
162 161
267 637
394 596
42 21
764 353
736 539
870 875
616 721
250 900
353 718
147 512
415 499
127 266
194 416
940 903
621 161
228 114
521 188
225 109
902 86
268 169
89 152
507 619
193 72
197 488
554 266
540 715
538 49
320 780
544 685
483 467
763 868
424 161
967 615
693 325
447 990
901 490
756 825
714 806
881 303
556 625
589 637
86 220
227 320
320 262
148 6
987 617
853 797
916 546
606 704
945 574
286 749
908 875
98 221
227 934
247 931
588 706
33 0
347 945
126 346
210 663
988 976
267 146
660 676
514 539
708 518
979 628
309 753
647 715
628 967
455 644
251 117
729 843
696 713
270 352
313 906
925 954
171 462
182 443
681 867
58 89
619 469
850 364
860 848
654 651
886 715
326 639
119 440
86 121
675 0
682 297
305 475
342 872
604 97
178 249
455 780
70 96
857 280
145 207
690 78
396 147
621 338
277 520
306 177
97 48
526 133
953 760
177 268
750 558
74 55
382 748
155 568
836 121
638 468
822 369
720 597
44 17
130 219
531 700
582 16
402 196
367 868
201 46
52 24
559 224
514 139
990 811
664 271
165 299
81 112
783 111
450 0
932 398
510 169
576 16
279 216
378 26
637 43
204 745
502 25
426 832
166 123
834 946
235 735
926 250
840 699
724 704
777 806
59 14
609 493
666 128
976 52
897 0
191 103
443 868
53 56

output
48
That's all for today's sharing. Thank you for visiting this konjaku post~~

Tags: Algorithm Dynamic Programming

Posted on Thu, 21 Oct 2021 20:46:32 -0400 by kyoru