Write a very good blog link: https://blog.csdn.net/xiaofei_it/article/details/17042651
Generating function normally solve problems similar to the following:
5 to 1 yuan, 2 yuan 4, 3 5 yuan, 15 yuan to get, how many combinations?
In certain cases require the use of at least three $ 1, a $ 2 0 5 yuan.
In certain cases there are numerous provisions 1 yuan, 2 yuan, 5 yuan.
……
In fact, most of the problems generating function can also be used dp / backpack to write, but I feel too weak dp easily mistake a template generating function is easier to understand better.
Next is my mother a few introductory function Topic:
I use here the last mark to optimize the efficiency of the generating function, so that a higher efficiency.
HDU1085
Meaning of the questions: coins in denominations of 2, 5, giving their number. The minimum amount of the composition is not asking much.
Ideas: generating function ran out of money for the program n the number of combinations of the number of species, from the beginning to traverse, the first program number is 0 n is the answer.
Code:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #define mem(a, b) memset(a, b, sizeof(a)) 5 using namespace std; 6 7 int val[5], num[5], last, last2; 8 int temp[8100], ans[8100]; 9 10 int main() 11 { 12 val[0] = 1, val[1] = 2, val[2] = 5; 13 while(scanf("%d%d%d", &num[0], &num[1], &num[2]) != EOF) 14 { 15 if(num[0] + num[1] + num[2] == 0) 16 break; 17 mem(ans, 0), mem(temp, 0); 18 last = 0, ans[0] = 1; 19 for(int i = 0; i < 3; i ++) 20 { 21 last2 = min(last + val[i] * num[i], 8100); 22 memset(temp, 0, sizeof(int) * (last2 + 1)); 23 for(int j = 0; j <= num[i] && j * val[i] <= last2; j ++) 24 { 25 for(int k = 0; k <= last && k + j * val[i] <= last2; k ++) 26 temp[k + j * val[i]] += ans[k]; 27 } 28 memcpy(ans, temp, sizeof(int) * (last2 + 1)); 29 last = last2; 30 } 31 for(int i = 0; i <= 8010; i ++) 32 { 33 if(ans[i] == 0) 34 { 35 printf("%d\n", i); 36 break; 37 } 38 } 39 } 40 return 0; 41 }
HDU2079
The meaning of problems: there are k rows, each row having two integers a (1 <= a <= 8), b (1 <= b <= 10), expressed as a class have credits b door. Output an integer representing the number of combinations of n learning credits.
Code:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #define mem(a, b) memset(a, b, sizeof(a)) 5 using namespace std; 6 7 int n, k; 8 int val[10], num[10]; 9 int last, last2, temp[50], ans[50]; 10 11 int main() 12 { 13 int T; 14 scanf("%d", &T); 15 while(T --) 16 { 17 last = 0; 18 mem(temp, 0), mem(ans, 0); 19 ans[0] = 1; 20 scanf("%d%d", &n, &k); 21 for(int i = 0; i < k; i ++) 22 scanf("%d%d", &val[i], &num[i]); 23 for(int i = 0; i < k; i ++) 24 { 25 last2 = min(last + val[i] * num[i], n); 26 memset(temp, 0, sizeof(int) * (last2 + 1)); 27 for(int j = 0; j <= num[i] && j * val[i] <= last2; j ++) 28 { 29 for(int k = 0; k <= last && k + j * val[i] <= last2; k ++) 30 { 31 temp[k + j * val[i]] += ans[k]; 32 } 33 } 34 memcpy(ans, temp, sizeof(int) * (last2 + 1)); 35 last = last2; 36 } 37 printf("%d\n", ans[n]); 38 } 39 return 0; 40 }
HDU2152
The meaning of problems: n kinds of fruit, the program obtains the number of combinations m of the fruit. But there are number of restrictions, there is an upper limit with the lower limit
Code:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #define mem(a, b) memset(a, b, sizeof(a)) 5 using namespace std; 6 7 int n, m, down[110], up[110]; 8 int last, last2; 9 int ans[110], temp[110]; 10 11 int main() 12 { 13 while(scanf("%d%d", &n, &m) != EOF) 14 { 15 for(int i = 0; i < n; i ++) 16 scanf("%d%d", &down[i], &up[i]); 17 mem(temp, 0), mem(ans, 0); 18 ans[0] = 1, last = 0; 19 for(int i = 0; i < n; i ++) 20 { 21 last2 = min(last + up[i], m); 22 memset(temp, 0, sizeof(int) * (last2 + 1)); 23 for(int j = down[i]; j <= up[i] && j <= last2; j ++) 24 { 25 for(int k = 0; k <= last && k + j <= last2; k ++) 26 { 27 temp[k + j] += ans[k]; 28 } 29 } 30 memcpy(ans, temp, sizeof(int) * (last2 + 1)); 31 last = last2; 32 } 33 printf("%d\n", ans[m]); 34 } 35 return 0; 36 }
template:
. 1 ANS [ 0 ] = . 1 , Last = 0 ; // initialize the plurality of sets of input words also MEM (ANS, 0), MEM (TEMP, 0) 2 for ( int I = 0 ; I <K; I ++ ) . 3 { . 4 last2 = min (last Val + [I] * NUM [I], n-); // time of the last calculation . 5 Memset (TEMP, 0 , the sizeof ( int ) * (+ last2 . 1 )); // only empty TEMP [0 ... last2] . 6 for ( int J = Down [I]; J <= up [I] && * J Val [I] <= last2; J ++) //Note that each of a number of factors traversing the upper and lower limits . 7 { . 8 for ( int K = 0 ; K <= J + K * Last && Val [I] <= last2; K ++) // iterate answer array update answer, before factor multiplication factor obtained by multiplying the provisional answer . 9 { // ANS is the last in the last, temp is in last2 10 TEMP [Val * K + J [I]] = + ANS [K]; . 11 } 12 is } 13 is the memcpy (ans, TEMP, the sizeof ( int ) * (+ last2 . 1 )); // TEMP assigned to a temporary answer to be updated ans 14 Last = last2; // update Last 15 }