ACM-Special Array

  题目描述: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 }

 



posted @ 2018-03-04 16:13  小小小的程序猿  阅读(173)  评论(0编辑  收藏  举报
window.onload = function(){ $("#live2dcanvas").attr("style","position: fixed; opacity: 0.7; left: 70px; bottom: 0px; z-index: 1; pointer-events: none;") }