I believe everyone has done it Roast Chicken This problem. but 10 10 10 cycles is too much trouble. To 100 , 1000 100,1000 100, 1000 cycles?
Subset enumeration!
1, Definition of subset enumeration
What is subset enumeration?
- For one data, if each data has only 2 2 Two states, for example: select or not, select the first or the second... At this time, subset enumeration becomes a good choice.
- Because each data has only 2 2 Two states, from which we can think of 2 2 Binary. 0 0 0 represents the first state, 1 1 1 represents the second state. At this time, the representation of each decimal number in binary represents a state.
2, Code implementation
#include <cstdio> #include <algorithm> using namespace std; int n; // n means there are several data in total // Subset enumeration void work() { int U = (1 << n); // (1 < < n) means pow(2, n). But the difference is that (1 < < n) is of type int and pow(2, n) is of type double. Choose according to the situation. // 0 (10) = 0000 (2) is an option, but u (10) = 100 0 (n zeros) is not a selection. So the enumeration range is [0, U). for(int S = 0; S < U; S++) /*Traverse each case*/ { if(/*Judgment statement*/ ) /*Execute statement*/; } /* Example: int ans = 0; for(int S = 0; S < U; S++) { if(__builtin_popcount(S) == k) // This function means to calculate the number of S in binary. ans++; } printf("%d", ans); */ printf(/*Output content*/); return ; // return. } int main() { scanf("%d", &n); work(); return 0; }
3, Examples
P1657 selected books
time limit
1.00s
Memory limit
125.00MB
Title Description
During the school winter vacation, the tutor of the Olympic Games of Informatics has 1, 2, 3... X books, which should be distributed to x people participating in the training. Each person can only choose one book, but each person has two favorite books. The teacher asked everyone to fill in a form with their favorite books in advance. Then distribute the books according to the form they fill in, hoping to design a program to help the teacher find out all possible distribution schemes and make every student satisfied.
Input format
Line 1: a number x
Line 2 ~ line 1+x: two numbers in each line, indicating the serial number of the book ai likes
Output format
There is only one number: total number of schemes.
Sample input and output
Enter #1 copy
5
1 3
4 5
2 5
1 4
3 5
Output #1 copy
2
Description / tips
All data: x < = 20
(there is not one of the most difficult data topics in the world...)
analysis
(it was originally daoshen search, but I wrote it as subset enumeration)
First, analyze the topic. Each student has only two favorite books, which can be regarded as two situations.
See code Notes for ideas:
#include <cstdio> #include <iostream> #include <memory.h> using namespace std; int n, U; int book[25][3]; int judge[25]; // input void input() { scanf("%d", &n); for(int i = 0; i < n; i++) for(int j = 0; j < 2; j++) scanf("%d", &book[i][j]), book[i][j]--; U = 1 << n; // printf("%d", U); return ; } /* Subset enumeration idea: Each person chooses two books a1, a2. Select a1 as 0 and a2 as 1. Define variable U, then U-1 is the complete set and the range is [0, U) . Operation (U & (1 < < i)) is to judge whether the ith student chose the first book or the second book. The value of 0 is the first book, and the value is not 0 It's the second book. */ // Subset enumeration void work(int U) { int ans = 0; int f = 1; for(int S = 0; S < U; S++) { f = 1; memset(judge, 0, sizeof(judge)); for(int i = 0; i < n; i++) if(S & (1 << i)) judge[book[i][1]]++; else judge[book[i][0]]++; for(int i = 0; i < n; i++) if(judge[i] != 1) { f = 0; break; } // printf("%d: ", S); // for(int i = 0; i < n; i++) // printf("%d ", judge[i]); // puts(""); if(f) { ans++; // printf("%d\n", S); } } printf("%d\n", ans); } int main() { input(); if(n == 0) { printf("0"); return 0; } work(U); return 0; }
4, Complexity analysis
The time complexity of subset enumeration is O ( 2 n ) O(2^n) O(2n), so there is nothing to do about the problem of too large data. general requirements n ≤ 20 n \le 20 n≤20.