C++计算排列与组合
排列
如果计算排列数,直接利用公式即可。下面的代码是输出每一种排列的情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
void permutate(vector<int>& nums, int left, int right, int& ans) { if(left == right){ ans++; for(int num: nums){ cout << num << " "; } cout << endl; return; } for(int i = left; i < right; i++){ swap(nums[i], nums[left]); permutate(nums, left + 1, right, ans); swap(nums[i], nums[left]); } return; }
|
组合
如果是需要输出每种组合的情况,可以还用回溯的思想
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
void combine(vector<int>& nums, int pos, int cnt, int K, int& ans, vector<bool>& visited) { if(cnt == K){ ans++; for(int i = 0; i < nums.size(); i++){ if(visited[i]){ cout << nums[i] << " "; } } cout << endl; return; } if(pos == nums.size()){ return; } visited[pos] = true; combine(nums, pos + 1, cnt + 1, K, ans, visited); visited[pos] = false; combine(nums, pos + 1, cnt, K, ans, visited); }
|
如果是只计算组合数,比较实用的是利用递推公式进行计算
这个公式的含义是从$m$个数中取出$n$个数,可以分为两种情况:
- 包括第$m$个数,此时只需要从前$m-1$个数中取出$n-1$个数,一共有$C_{m-1}^{n-1}$种情况;
- 不包括第$m$个数,此时只需要从前$m-1$个数中取出$n$个数,一共有$C_{m-1}^{n}$种情况。
1 2 3 4 5 6 7 8 9 10 11 12
| int combine(int m, int n) { vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0)); for(int i = 0; i <= m; i++){ dp[i][0] = 1; for(int j = 1; j <= min(i, n); j++){ dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1]; } } return dp[m][n]; }
|