import java.io.*; import java.util.*; import java.awt.geom.*; /** * Solution to Skyscrapers * * @author vanb */ public class skyscrapers_vanb { public Scanner sc; public PrintStream ps; // Mod value specified in the problem public static final long MOD = 1000000007L; // Max n public static final int MAX = 5000; // Memoization for the answers public long memo[][] = new long[MAX+1][MAX+1]; // Memoization for combinations public long cmemo[][] = new long[MAX+1][MAX+1]; /** * Combinations. This is a little different - it's combinations of a+b things taken a at a time. * * @param a A number * @param b Another number * @return Combinations of a+b things taken a at a time */ public long combs( int a, int b ) { // We'll memoize if( cmemo[a][b]==0 ) { long result = combs( a-1, b ) + combs( a, b-1 ); cmemo[a][b] = cmemo[b][a] = result % MOD; } return cmemo[a][b]; } /** * The number of ways to arrange n things so that k of them * can be seen from one side. * * @param n Size of permutation * @param k Number of things that can be seen * @return The number of ways as specified above */ public long ways( int n, int k ) { if( memo[n][k]<0L ) { long result = 0L; // Consider the last building. // If it's the biggest one, it's going to be seen, // no matter what. So, wee need to see k-1 of the remaining n-1 result += ways( n-1, k-1 ); result %= MOD; // What if the last building isn't the biggest one? // Then it's going to be hidden by the biggest one. // That means we need to see k of the remaining n-1 // And, there are n-1 ways of selecting that last building without // it being the biggest one. result += (n-1)*ways( n-1, k ); result %= MOD; memo[n][k] = result; } return memo[n][k]; } /** * Driver. * @throws Exception */ public void doit() throws Exception { sc = new Scanner( System.in ); //new File( "skyscrapers.judge" ) ); ps = System.out; //new PrintStream( new FileOutputStream( "skyscrapers.vanb" ) ); // Initialize the memoization arrays for( int i=0; i<=MAX; i++ ) { Arrays.fill( memo[i], -1 ); memo[i][i] = 1L; memo[i][0] = 0L; cmemo[i][0] = cmemo[0][i] = 1L; } cmemo[0][0] = memo[0][0] = 1L; for(;;) { int n = sc.nextInt(); int left = sc.nextInt(); int right = sc.nextInt(); if( n==0 ) break; long allways = 0L; // Consider every possible position for the biggest building for( int i=left-1; i<=n-right; i++ ) { // This is the number of ways to see the buildings on the left long result = ways( i, left-1 ); // This is the number of ways to see the buildings on the right result *= ways( n-i-1, right-1 ); result %= MOD; // This is the number of ways to split the remaining // n-1 buildings around the biggest building if it's // at position i result *= combs( i, n-i-1 ); result %= MOD; allways += result; allways %= MOD; } ps.println( allways ); System.out.println( allways ); } } /** * @param args */ public static void main( String[] args ) throws Exception { new skyscrapers_vanb().doit(); } }