复杂的递归功能 - 在房间和人之间分配星星

时间:2015-11-08 11:52:27

标签: c# algorithm recursion

假设我有星星总数n,有房间,每个房间最多可容纳3人。我想知道有多少组合我可以分发星星知道一个人可以拥有最多7颗星。

例如,我总共有4颗星。一种可能的解决方案是:

room: person *
room: person *
room: person *
room: person *

another possible is
room: person ****

another just in case is
room: person* person* person*
room: person *

public class SolutionData
{
        public class PackData
        {
            public List< int > people; // number of stars
            public PackData( )
            {
                people= new List<int>( );
            }
        }

        public List< PackData > packs;

        public SolutionData( )
        {
            packs = new List< PackData >( );
        }
}

有什么方法可以填充包含所有可能性的solutionData数组吗?

我有什么

static void GetSolutions( int totalRank , ref List< SolutionData > solutions )
{
    if( totalRank == 0 ) return;

    if( totalRank >= 1 ) GetSolutions( totalRank - 1 , ref solutions );
    if( totalRank >= 2 ) GetSolutions( totalRank - 2 , ref solutions );
    if( totalRank >= 3 ) GetSolutions( totalRank - 3 , ref solutions );
    if( totalRank >= 4 ) GetSolutions( totalRank - 4 , ref solutions );
    if( totalRank >= 5 ) GetSolutions( totalRank - 5 , ref solutions );
    if( totalRank >= 6 ) GetSolutions( totalRank - 6 , ref solutions );
    if( totalRank >= 7 ) GetSolutions( totalRank - 7 , ref solutions );
}

在某些时候我必须填写解决方案,但我真的不知道在哪里以及如何。我甚至不知道部分功能是否正确。

注意:房间/包装没有限制,显然最大数量是总星数n。总星数n不会很高,最高可达20-30。

1 个答案:

答案 0 :(得分:2)

  

有什么方法可以填充包含所有可能性的solutionData数组吗?

我不会采用这种方法。如果目标是创建一组组合,那么将返回一组组合。不要拿一个数组并填写它。该方法有什么用处?星数。什么出来?这组合。该方法应具有签名:

static IEnumerable<SolutionData> GetSolutions(int totalRank)

您希望创建一个递归解决方案,并且您具有递归解决方案的草图:

  • 你有一个简单的基础案例。你似乎有零星的解决方案 - 也就是说,没有解决方案 - 但这可能没那么有用。 鉴于零星的解决方案,你能为一颗恒星构建解决方案吗?这就是你需要做的。如果你不能这样做那么基本情况必须是一个星,而不是零。

  • 一种简化为较小问题的递归案例。假设您寻求10星的解决方案,并且您已经拥有9星级的解决方案。你能用9星的解决方案来构建10星的解决方案吗?如果没有,那么算法将不会是递归的。现在概括一下;如果你有一个n-1星的解决方案,你能从这个信息创建一个解决n星问题的解决方案吗?

所以你的方法将采用以下形式:

if (in the base case)
    return the trivial solution
else
    solve a smaller problem recursively
    construct the solution to the larger problem from that solution
    return the solution

在这里你似乎陷入困境的是为解决较小的问题提供新的解决方案。专注于此。假设您希望解决10的问题,在这里,我会神奇地为您提供9的解决方案。您将如何利用这些信息?

现在,一旦你拥有它,它可能太慢而不可行。评论提到动态编程,这是以下技术:

if (in the base case)
    return the trivial solution
else if (we have solved this problem before and remember the solution)
     return the previous solution
else
    solve a smaller problem recursively
    construct the solution to the larger problem from that solution
    make a note in global state of the solution to this problem
    return the solution

动态编程的想法是许多递归算法花费大量时间重新解决他们在几纳秒之前已经解决的问题。如果您刻录额外的内存以记住解决方案,则可以在重新计算时节省。