计算机二级C语言辅导:回溯法之数的划分
来源:优易学  2011-12-10 16:53:43   【优易学:中国教育考试门户网】   资料下载   IT书店
  #include <iostream>
  #include <vector>
  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<int> Record(int m, int n, int k)
  {
  vector<int> 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<int> 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;
  }

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训