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

题目大意:这是一道简单排列组合题 。简单说下题意: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 }

 

转载于:https://www.cnblogs.com/20143605--pcx/p/4687268.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值