Gym 100345B Signed Derangements
Problem B. Signed Derangements Input file: derangements.in Output file: derangements.out Time limit: 1 second Memory limit: 256 megabytes Signed permutation of size n is an ordered set of n numbers ranging from −n to n except 0, where absolute values of any two numbers are different. An example of a signed permutation is ⟨4, −2, 3, −5, −1⟩. Clearly, there are 2nn! signed permutations of size n. A signed permutation ⟨a1, a2, . . . , an⟩ is called a signed derangmenent if ai ̸= i for all i. For example, ⟨4, −2, 3, −5, −1⟩ is not a signed derangement, but ⟨4, −2, −3, −5, −1⟩ is. Given n, find the number of signed derangements of size n. Input Input file contains one integer number n (1 ≤ n ≤ 200). Output Output one integer number — the number of signed derangements of size n. Example derangements.in derangements.out 2 5 The following signed 2-permutations are signed derangements: ⟨2, 1⟩, ⟨2, −1⟩, ⟨−2, 1⟩, ⟨−1, −2⟩, and ⟨−2, −1⟩.
容斥原理
import java.util.*; import java.io.*; import java.math.*; public class Main { /** * @param args */ public static void main(String[] args) throws FileNotFoundException { // TODO Auto-generated method stub Scanner cin = new Scanner (new File("derangements.in")); PrintWriter cout = new PrintWriter(new File("derangements.out")); //Scanner cin = new Scanner (System.in); BigInteger [][] C = new BigInteger [210][210]; BigInteger [] N = new BigInteger [210]; BigInteger [] Two = new BigInteger [210]; BigInteger two; two=BigInteger.ONE; two=two.add(two); C[0][0]=BigInteger.ONE; for (int i=1;i<=200;i++) { C[i][0]=C[i][i]=BigInteger.ONE; for (int j=1;j<i;j++) { C[i][j] = BigInteger.ZERO; C[i][j]=C[i][j].add(C[i-1][j-1]); C[i][j]=C[i][j].add(C[i-1][j]); } } N[0] = BigInteger.ONE; for (int i=1;i<=200;i++) { BigInteger tp = new BigInteger(String.valueOf(i)); N[i] = N[i-1].multiply(tp); } Two[0] = BigInteger.ONE; for (int i=1;i<=200;i++) { Two[i] = Two[i-1].multiply(two); } int n; n = cin.nextInt(); BigInteger ans = BigInteger.ZERO; ans=Two[n].multiply(N[n]); int cur=0; for (int i=1;i<=n;i++){ if (cur==0) { BigInteger tp = C[n][i].multiply(Two[n-i]); tp=tp.multiply(N[n-i]); ans=ans.subtract(tp); cur=1-cur; } else { BigInteger tp = C[n][i].multiply(Two[n-i]); tp=tp.multiply(N[n-i]); ans=ans.add(tp); cur=1-cur; } } cout.println(ans); //System.out.println(ans); cin.close(); cout.close(); } }