洛谷P1025 [NOIP2001 提高组] 数的划分

题目描述

将整数 n 分成 k 份,且每份不能为空,任意两个方案不相同(不考虑顺序)。

例如:n=7,k=3,下面三种分法被认为是相同的。

1,1,5;
1,5,1;
5,1,1.

问有多少种不同的分法。

输入格式

n, k (6 < n ≤ 200, 2 ≤ k ≤ 6)

输出格式

11 个整数,即不同的分法。

输入输出样例

输入

7 3                                                                     

输出

4                                                                 

说明/提示

四种分法为:
1, 1, 5;
1, 2, 4;
1, 3, 3;
2, 2, 3.

代码

#include 
using namespace std;
int main()
{
    int n,k;
    cin >> n >> k;
    int sum = 0;
    for(int i1 = 1; i1 <= n / 2; i1 ++)
    {
        for(int i2 = i1; i2 <= n / 2 ;i2 ++)
        {
            for(int i3 = i2; i3 <= n / 2; i3 ++)
            {
                for(int i4 = i3; i4 <= n / 2; i4 ++)
                {
                    for(int i5 = i4; i5 <= n / 2; i5 ++)
                    {
                        if(k == 2)
                        {
                            if(i5 <= n - i5) sum ++;
                        }
                        else if(k == 3)
                        {
                            if(i4 <= n - i4 - i5 && i5 <= n - i4 - i5) sum ++;
                        }
                        else if(k == 4)
                        {
                            if(i4 <= n - i4 - i5 - i3 && i5 <= n - i4 - i5 - i3 && i3 <= n - i3 - i4 - i5) sum ++;
                        }
                        else if(k == 5)
                        {
                            if(i4 <= n - i4 - i5 - i3 - i2 && i5 <= n - i4 - i5 - i3 - i2 && i3 <= n - i3 - i4 - i5 - i2 && i2 <= n - i3 - i4 - i5 - i2) sum ++;
                        }
                        else if(k == 6)
                        {
                            if(i4 <= n - i4 - i5 - i3 - i2 - i1 && i5 <= n - i4 - i5 - i3 - i2 - i1 && i3 <= n - i3 - i4 - i5 - i2 - i1 && i2 <= n - i3 - i4 - i5 - i2 - i1 && i1 <= n - i3 - i4 - i5 - i2 - i1) sum ++;
                        }
                    }
                    if(k < 3) break;
                }
                if(k < 4) break;
            }
            if(k < 5) break;
        }
        if(k < 6) break;
    }
    cout<

题解思路

起初看完此题,我认为其应该使用递归来实现,但经过我一系列的尝试之后不是死循环就是结果错误。为了解开此题我使用了暴力解法。

分为 k 个数,那么肯定是从前 k-1 个数都是 1 时开始的,随后第 k-1 个数不断加1,第k个数不断减1直到第 k-1 个数小于等于第 k 个数。例如 (1 1 5,1 2 4,1 3 3)

再将第 k-2 个数加1,注意此时的第 k-1 个数从与前一个数字一样开始。例如(2 2 3)然后重复上面的操作。不断循环即可。

注:暴力解法只是在理解题意且题目实在写不出来时使用,做完以后最好能够去理解正确的解法。

【题目来源】

NOIP 2001 提高组第二题

你可能感兴趣的:(C++,c++)