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~~