码迷,mamicode.com
首页 > 其他好文 > 详细

UVA-10497 Sweet Child Makes Trouble (计数+高精度)

时间:2015-07-29 21:01:36      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:这是一道简单排列组合题 。简单说下题意:n件物品,把这n件物品放到不是原来的位置,问所有的方案数。所有的位置都没有变。

题目解析:按照高中的方法,很快得到一个递推公式:f [n]= (n-1)*( f [n-1] + f [n-2] ) 。这个公式也不难理解,可以采取这样的策咯:一件物品一件物品的放,则第一件物品,假设编号1,有n-1个位置可放,假如放到原来物品 2 的位置,则再放物品 2,依次进行下去......也就是放到的位置上原来是哪个物品则下一个就放该物品 。按照这种策咯,放第一件物品时,有n-1种选择,还是假如放到了2号物品原来的位置,那么,就放2号物品,2号物品的选择有两类,一类是物品 1 的原来位置(这类中有且只有一个位置),另一类不是物品 1 的原来位置,选择了前一类方位置时,第二步有 f(n-2)种方案,当选择第二类位置时相当于有 f(n-1) 种方案 。根据加法原理,第二步有 f(n-2)+f(n-1)种方案,根据乘法原理总共有 (n-1)*(f(n-2)+f(n-1)) 方案 。

注意:最后的结果比较坑,要用到高精度,不过,下文代码中的高精度不是按10进制的高精度写的,而是按10^6进制的高精度写的 。

 

代码如下:

 1 # include<iostream>
 2 # include<cstdio>
 3 # include<cstring>
 4 # include<algorithm>
 5 using namespace std;
 6 const int N=1000000;
 7 int ans[805][550];
 8 void init()
 9 {
10     memset(ans,0,sizeof(0));
11     ans[1][0]=ans[2][0]=1;
12     ans[1][1]=0,ans[2][1]=1;
13     for(int i=3;i<=800;++i){
14         for(int j=1;j<=ans[i-1][0];++j){
15             ans[i][j]+=(i-1)*(ans[i-1][j]+ans[i-2][j]);
16             ans[i][j+1]+=(ans[i][j]/N);
17             ans[i][j]%=N;
18         }
19         for(int j=ans[i-1][0];;++j){
20             if(!ans[i][j])
21                 break;
22             ans[i][0]=j;
23         }
24     }
25 }
26 int main()
27 {
28     init();
29     int n;
30     while(scanf("%d",&n))
31     {
32         if(n==-1)
33             break;
34         if(n==1){
35             printf("0\n");
36             continue;
37         }
38         for(int i=ans[n][0];i>=1;--i){
39             if(i==ans[n][0]&&ans[n][i])
40                 printf("%d",ans[n][i]);
41             else
42                 printf("%06d",ans[n][i]);
43         }
44         printf("\n");
45     }
46     return 0;
47 }

 

UVA-10497 Sweet Child Makes Trouble (计数+高精度)

标签:

原文地址:http://www.cnblogs.com/20143605--pcx/p/4687268.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!