If you want to exchange 100 yuan, there are four kinds of money: 1, 2, 5, and 10. How many exchange methods are there in total?
recursive solution
1 #include<iostream> 2 using namespace std; 3 4 const int N = 100 ; 5 int dimes[] = { 1 , 2 , 5 , 10 }; 6 int arr[N+ 1 ] = { 1 }; 7 8 int coinExchangeRecursion( int n, int m) // Recursive implementation, better understanding 9 { 10 if (n == 0 ) // 11 return 1 ; 12 if (n < 0 || m == 0 ) 13 return 0 ; 14 15 return ( coinExchangeRecursion (n, m- 1 ) + coinExchangeRecursion(n-dimes[m- 1 ], m )); 16 // There are two cases: the case of exchanging the current face value + the case of not exchanging the current face value 17 } 18 19 int main() 20 { 21 int num=coinExchangeRecursion(N, 4 ); 22 cout<<num << endl; 23 24 return 0; 25 26 }
non-recursive solution
1 #include<iostream> 2 using namespace std; 3 4 const int N = 100 ; 5 int dimes[] = { 1 , 2 , 5 , 10 }; 6 int arr[N+ 1 ] = { 1 }; 7 8 int coinExchange( int n) // non-recursive implementation 9 { 10 int i, j; 11 // i is from 0 to 3 because each arr[j] has to be exchanged once, assuming dimes[i] is exchanged, so we have to traverse once 12 for (i = 0 ; i < sizeof (dimes)/ sizeof ( int ); i++ ) 13 { 14 for (j = dimes[i]; j <= n; j++ ) 15 // seek, arr[j] When, it can be seen that arr[j] = arr[j] + arr[j-dimes[i]], 16 // Corresponding to the above recursive method: arr[j] is coinExchangeRecursion(n, m-1), 17 // arr[j-dimes[i]] is coinExchangeRecursion(n-dimes[m-1], m) 18 arr[j] += arr[j- dimes[i]]; 19 20 } 21 return arr[n ]; 22 } 23 24 25 int main() 26 { 27 int num2=coinExchange(N); 28 cout<<num2<<endl; 29 30 return 0; 31 }
Method summary
The classic point of dynamic programming is to decompose a big problem into several small problems to solve the
recursive algorithm: the exchange of 100 yuan: there are two situations in which there is this face value in the change and there is no such face value in the change, pay attention to the conditional
non-recursive algorithm for the end of the recursion: To change 100 coins, then start from the change of 1, 2, ..., this algorithm, it is best to convert it into a step-by-step problem to understand
and reason carefully. It can be seen that arr[j] = arr[j-dimes[ 0]] + arr[j-dimes[1]] + arr[j-dimes[2]] + arr[j-dimes[3]] (j-dimes[i]>=0)
1 #include<iostream> 2 #include<vector> //std::vector 3 #include <algorithm> //std::count 4 using namespace std; 5 6 const int N = 100; 7 int dimes[] = {1, 2, 5, 10}; 8 int arr[N+1] = {1}; 9 vector<int> vv; 10 11 int coinExchangeRecursion(int n, int m) //递归方式实现,更好理解 12 { 13 if (n == 0) { 14 int i; 15 for (i = 0; i < sizeof(dimes)/sizeof(int); i++) { 16 int cnt = count(vv.begin(), vv.end(), dimes[i]); 17 cout << dimes[i] << ": " << cnt << "\t"; 18 } 19 cout << endl; 20 return 1; 21 } //跳出递归的条件 22 if (n < 0 || m == 0) 23 return 0; 24 vv.push_back(dimes[m-1]); 25 int yes = coinExchangeRecursion(n-dimes[m-1], m); 26 vv.pop_back(); 27 int no = coinExchangeRecursion(n, m-1); 28 return (no+yes); 29 //Divided into two cases, if the current coin is not changed, how much is it? In addition, if the current coin is changed and the total value is reduced, how many exchange methods are there at this time? 30 } 31 32 int coinExchange( int n) // non-recursive implementation 33 { 34 int i, j; 35 for (i = 0 ; i < sizeof (dimes)/ sizeof ( int ); i++) // i from 0 ~ 3 Because each arr[j] has to be exchanged once to assume dimes[i], so we have to traverse 36 { 37 for (j = dimes[i]; j <= n; j++ ) 38 // Seek, When arr[j], it can be seen that arr[j] = arr[j] + arr[j-dimes[i]], 39 //Corresponding to the recursive method above: arr[j] is coinExchangeRecursion(n, m-1), 40 // arr[j-dimes[i]] is coinExchangeRecursion(n-dimes[m-1], m) 41 arr[ j] += arr[j- dimes[i]]; 42 } 43 return arr[n]; 44 } 45 46 int main( int argc, char * argv[]) 47 { 48 int num=coinExchangeRecursion(N, 4 ); 49 cout<<num<< endl; 50 51 int num2= coinExchange(N); 52 cout<<num2<<endl; 53 54 return 0; 55 }
Reference link:
http://www.cnblogs.com/sdjl/articles/1274312.html
https://www.tuicool.com/articles/VBreAnY