题目描述:Special array
输入n和m(20>=m>=n>0)求出所有满足以下方程的正整数数列 i1,i2,...,in,使i1+i2+...+in=m,且i1>=i2...>=in。例如:当n=4, m=8时,将得到如下5 个数列: 5 1 1 1 4 2 1 1 3 3 1 1 3 2 2 1 2 2 2 2
输入
输入只有一行,包含每个数列的元素个数n和数列元素的和m。
输出
按照字典逆序输出所有的数列,每个数列输出一行,每个数列元素用一个空格分开。
样例输入
4 8
样例输出
5 1 1 1 4 2 1 1 3 3 1 1 3 2 2 1 2 2 2 2
解题思路:很简单的一道DFS题目,减枝策略可以除了常规的策略之外,再加上当前搜索数目最大不超过剩余数-剩余位置个数。
1 // specical array.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 6 7 #include <iostream> 8 #include <cstring> 9 using namespace std; 10 const int MAX = 50; 11 int n, m, arr[MAX]; 12 13 //最后一个数,已经填数的个数,数组总和 14 void DFS(int cur, int cnt, int sum) 15 { 16 if (cnt == n) 17 { 18 if (sum == m) 19 { 20 for (int i = 0; i < n; i++) 21 { 22 if (i != n - 1) cout << arr[i] << " "; 23 else cout << arr[i] << endl; 24 25 } 26 } 27 return; 28 29 } 30 for (int i = cur; i >= 1; i--) // 从大到小开始搜索 31 { 32 if (i + sum + n - cnt - 1 <= m) //n-cnt-1 是剩余大小 33 { 34 arr[cnt] = i; 35 DFS(i, cnt + 1, sum + i); 36 } 37 38 } 39 } 40 41 42 int main() 43 { 44 while (cin >> n >> m) 45 { 46 memset(arr, 0, sizeof(arr)); 47 48 for (int i = m - n + 1; i >= 1; i--) 49 { 50 arr[0] = i; 51 DFS(i, 1, i); 52 } 53 } 54 55 return 0; 56 }