hdu2049(排列)

来源:互联网 发布:数据采集仪数据存储 编辑:程序博客网 时间:2024/05/18 02:30

组合公式+错排

错排递推:

第一步,“错排” 1 号元素(将 1 号元素排在第 2 至第 n 个位置之一),有 n - 1 
种方法。

第二步,“错排”其余 n - 1 个元素,按如下顺序进行。视第一步的结果,若 1 
号元素落在第 k 个位置,第二步就先把 k 号元素“错排”好, k 
号元素的不同排法将导致两类不同的情况发生:( 1 ) k 号元素排在第 1 
个位置,留下的 n - 2 个元素在与它们的编号集相等的位置集上“错排”,有 f(n -2) 
种方法;( 2 ) k 号元素不排第 1 个位置,这时可将第 1 个位置“看成”第 k 
个位置,于是形成(包括 k 号元素在内的) n - 1 个元素的“错排”,有 f(n - 1) 
种方法。据加法原理,完成第二步共有 f(n - 2)+f(n - 1) 种方法。


错排公式为:f [i ] =(i-1)*( f [ i-1 ] + f [ i-2 ] )

通式 : f(n)=n! (1/2!-1/3!+······+(-1)^n/n!)

#include<stdio.h>#include<string.h>__int64 a[21];void fun1()//错排{    a[1]=0;a[2]=1;    for(__int64 i=3;i<=20;i++)     a[i]=(i-1)*(a[i-2]+a[i-1]);}__int64 fun2(__int64 t){    __int64 sum=1,i;    for(i=2;i<=t;i++)      sum=sum*i;    return sum;}__int64 c(__int64 t1,__int64 t2){    return fun2(t1)/fun2(t1-t2)/fun2(t2);}int main(){    //fun1();    int ncase;    __int64 n,m;    scanf("%d",&ncase);    while(ncase--)    {        scanf("%I64d%I64d",&n,&m);        printf("%I64d\n",c(n,m)*a[m]);    }    return 0;}

hdu 2048 

#include<stdio.h>#include<string.h>__int64 a[21];void fun1()//错排{    a[1]=0;a[2]=1;    for(__int64 i=3;i<=20;i++)     a[i]=(i-1)*(a[i-2]+a[i-1]);}__int64 fun2(__int64 t){    __int64 sum=1,i;    for(i=2;i<=t;i++)      sum=sum*i;    return sum;}int main(){    fun1();    int ncase;    __int64 n;    scanf("%d",&ncase);    while(ncase--)    {        scanf("%I64d",&n);        printf("%.2lf",a[n]*1.0/fun2(n)*100);        puts("%");    }    return 0;}

java代码:

import java.math.*;import java.io.*;import java.util.*;public class Main {// final long []b = new long[3000];static final long[] a = new long[21];public static void fun1() {a[1] = 0;a[2] = 1;for (int i = 3; i <= 20; i++) {a[i] = (i - 1) * (a[i - 2] + a[i - 1]);}}public static long fun2(long t) {long sum = 1, i;for (i = 2; i <= t; i++) {sum = sum * i;}return sum;}public static void main(String[] args) {Scanner cin = new Scanner(System.in);fun1();long ncase, n;double ans;ncase = cin.nextLong();for (long i = 1; i <= ncase; i++) {n = cin.nextLong();ans = a[(int) (n)] * 1.0 / fun2(n) * 100;System.out.printf("%.2f", ans);System.out.println("%");}}}

hdu2068 代码:

#include<string.h>#include<stdio.h>__int64 a[13]={1};void fun1()//错排{    a[1]=0;a[2]=1;    for(__int64 i=3;i<=12;i++)     a[i]=(i-1)*(a[i-2]+a[i-1]);}__int64 c(__int64 n,__int64 m){    __int64 z=1,f=1,i;    if(m>n/2) m=n-m;    for(i=1;i<=m;i++)    {        z=z*(n-i+1);        f=f*i;    }    return z/f;}int main(){    fun1();    __int64 n;    while(scanf("%I64d",&n)&&n)    {        __int64 sum=0;        for(int i=0;i<=n/2;i++)        {            sum+=c(n,n-i)*a[i];        }        printf("%I64d\n",sum);    }    return 0;}