POJ 2576 Tug of War
At the beginning, I had been struggling with how to record the number of people, because the idea at the beginning was that dp [I] [j] indicates whether I personally could reach the j value, and I thought about using the state compression storage path, then it was found that State compression was only applicable to the number of people <20, and the time and space complexity was acceptable. I also thought about using arrays to store the number of people, but it was not easy to operate. I read other people's problem-solving reports, I found that I think too much about it. Here I don't need to know the path. I just need to know how many people can reach the j value. Therefore, if you directly add a status to indicate the number of people, the status becomes: dp [I] [k] [j] indicates whether the j value can be reached when you select k people for the first I people
Then, considering the space complexity, the I state is omitted, and the reverse order is used to ensure that each person selects only one
# Include
# Include
Int dp [105] [45005], w [105]; int n; void init () {memset (dp, 0, sizeof (dp )); dp [0] [0] = 1;} int main () {# ifndef ONLINE_JUDGEfreopen ("in.txt", "r", stdin); # endifscanf ("% d ", & n); int sum = 0; for (int I = 1; I <= n; I ++) {scanf ("% d", & w [I]); sum + = w [I];} init (); for (int I = 1; I <= n; I ++) {for (int j = sum; j-w [I]> = 0; j --) {for (int k = n/2 + 1; k> = 1; k --) {if (dp [k-1] [j-w [I]) {dp [k] [j] = dp [k-1] [j-w [I] ;}}}for (int I = sum/2; I> = 0; I --) {if (n & 1) {if (dp [n/2] [I] | dp [n/2 + 1] [I]) {printf ("% d \ n", I, sum-I); break ;}} else {if (dp [n/2] [I]) {printf ("% d \ n", I, sum-I); break ;}} return 0 ;}