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 }
时间: 2024-11-17 00:09:50

UVA-10497 Sweet Child Makes Trouble (计数+高精度)的相关文章

uva 10497 - Sweet Child Makes Trouble(dp+高精度)

题目链接:uva 10497 - Sweet Child Makes Trouble 题目大意:有个小屁孩很淘气,总是趁父母不在家的时候去拿家具玩,每次拿n个家具玩,但是放回去的时候一定不会将某个物品放回原处,一定要打乱.问说有多少放的方式满足. 解题思路:dp[i]表示说i个数打乱的情况,dp[i]=(dp[i?1]+dp[i?2])?(i?1)每次新增一个数,放在序列的最后一个位置,它的位置一定是正确的,所以一定要和前面i?1个的其中一个交换位置才可以,那么如果选中位置上的物品为错误归放的,

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

题目链接:10497 - Sweet Child Makes Trouble 题意:n个物品,原来物品属于一个地方,现在要把物品重新放回去,问能放几种使得每个物品都与原来位置不同 思路:递推,一开始随便搞了个二维状态,dp[i][j]表示i个物品,有j个位置不同,那么dp[n][n]就是答案,递推式为: dp[i][j] = 1 (j == 0) dp[i][j] = (j - 1) * dp[i - 1][j - 1] + dp[i - 1][j] + (i - j + 1) * dp[i -

UVA - 10497 Sweet Child Makes Trouble

Children are always sweet but they can sometimesmake you feel bitter. In this problem, you will see how Tintin, a five year'sold boy, creates trouble for his parents. Tintin is a joyful boy and is alwaysbusy in doing something. But what he does is no

递推+高精度 UVA 10497 Sweet Child Makes Trouble(可爱的孩子惹麻烦)

题目链接 题意: n个物品全部乱序排列(都不在原来的位置)的方案数. 思路: dp[i]表示i个物品都乱序排序的方案数,所以状态转移方程.考虑i-1个物品乱序,放入第i个物品一定要和i-1个的其中一个交换位置,即:考虑i-2个物品乱序,第i-1个和第i个首先在原来的位置,两种方法使得乱序,一种和第i个交换(不能和前i-2个交换,那样成dp[i-1]),还有一种是第i个先和第i-1个交换,再和前i-2个其中一个交换,即,仔细想想,这个和dp[i-1]是不同的交换方法. 另外: 还有二维的dp写法,

sgu294:He&#39;s Circles(polya计数+高精度)

题目大意: 一个长度为 n(1≤n≤200000) 的环由 0 or 1 组成,求有多少本质不同的环. 分析: (这题有可能更侧重于考高精度) 考虑循环节的个数只可能为 n 的约数,且循环节的个数为 d 的置换会出现 φ(n/d) 次,所以答案就是: Σ2dφ(n/d)n (好大的公式...) 高精度压压位,优化一下常数就过了. AC code: #include <bits/stdc++.h> #define pb push_back #define mp make_pair #define

UVA 12075 - Counting Triangles(容斥原理计数)

题目链接:12075 - Counting Triangles 题意:求n * m矩形内,最多能组成几个三角形 这题和UVA 1393类似,把总情况扣去三点共线情况,那么问题转化为求三点共线的情况,对于两点,求他们的gcd - 1,得到的就是他们之间有多少个点,那么情况数就可以求了,然后还是利用容斥原理去计数,然后累加出答案 代码: #include <stdio.h> #include <string.h> #include <algorithm> using nam

uva 10766 Organising the Organisation 生成树计数

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1707 题意:给出n, m, k.表示n个点,其中m条边不能直接连通,求生成树个数. 思路:参考周冬的<生成树的计数及其应用>.就是Matrix-Tree定理的应用. 对于一个无向图G,它的生成树个数等于其Kirchhoff矩阵任何一个n-1阶主子式的行列式的绝对值.

UVa 1639 Candy (数学期望+组合数学+高精度存储)

题意:有两个盒子各有n个糖,每次随机选一个(概率分别为p,1-p),然后吃掉,直到有一次,你打开盒子发现,没糖了! 输入n,p,求另一个盒子里糖的个数的数学期望. 析:先不说这个题多坑,首先要用long double来实现高精度,我先用的double一直WA,后来看了题解是用long double, 改了,可一直改不对,怎么输出结果都是-2.00000,搞了一晚上,真是无语,因为我输入输出数据类型是long double, 结果一直不对 ,可能是我的编译器是C89的吧,和C语言,输入输出格式不同

UVA 1264 - Binary Search Tree(BST+计数)

UVA 1264 - Binary Search Tree 题目链接 题意:给定一个序列,插入二叉排序树,问有多少中序列插入后和这个树是同样的(包含原序列) 思路:先建树,然后dfs一遍,对于一个子树而言,仅仅要保证左边和右边顺序对就能够了,所以种数为C(左右结点总数,左结点),然后依据乘法原理乘上左右子树的情况就可以 代码: #include <cstdio> #include <cstring> typedef long long ll; const int MAXNODE =