补充男性荷尔蒙:回溯法之数的划分

来源:百度文库 编辑:九乡新闻网 时间:2024/07/08 15:53:25

回溯法之数的划分

做IT就要做精英,至少4000/月吧?
JAVAV工程师权威认证
[上海央邦]学一送一,超值! 【安博亚威】CCIE考试通过率第一!
定向委培RHCA,通过考试年薪10W
Windows高级工程师的培训地 中国IT实验室收集整理 佚名 2009-9-25 保存本文 推荐给好友 收藏本页 欢迎进入C/C++编程社区论坛,与200万技术人员互动交流 >>进入

#include

 #include

  using namespace std;

  long long r[221][11][221];

  int f(int m, int n, int c)

  {

     //只要分成两列,在首位数字确定的情况下只可能有一种分法

     if( n <= 2 )

         return 1;

     int i;

     int result = 0;

     int max = (m - c) / (n - 1);//首位数字最大值

     int tmp = 0;

     for(i = c; i <= max; i++)

      {

         if( r[m - c][n - 1][i] == 0 )

          {

             r[m - c][n - 1][i] = f(m - c, n - 1, i);

         }

         result += r[m - c][n - 1][i];

     }

     r[m][n][c] = result;

 

     return result;

 } 

 

 vector Record(int m, int n, int k)

  {

     vector s;

     int i;

     for( i = 1; i <= m / n; i++)

      {

         f(m, n, i);//按需调用

         if(r[m][n][i] < k)

          {

             k -= r[m][n][i];//如果当前的次序不够k, 把k减少,相当于从i + 1 后找第k'名

         }

         else

          {

             s.push_back(i);//存储路径

             if( n == 2 )

              {

                 s.push_back(m - i);//列数为2的时候,存储两列,退出

                 break;

             }

             else

              {

                 m -= i;//修改m为首位后面的数字和

                 --n;//行数减少了1

                 --i;//为了保持i不变,这里减少了1

             }

         }

     }

     return s;

 }

 

 void Output(vector seq)

  {

     int size = seq.size();

     if(size > 0 )

      {

         cout << seq[0] ;

         for(int i = 1; i < size; i++)

             cout << ' ' << seq[i];

         cout << endl;

     }

 }

 

 int main()

  {

     int m, n, k;

     while( cin >> m >> n >> k )

      {

         Output(Record(m, n, k));

     }

     return 0;

 }