Tarly has two different type of items, food boxes and wine barrels. There are f food boxes and w wine barrels. Tarly stores them in various stacks and each stack can consist of either food boxes or wine barrels but not both. The stacks are placed in a line such that no two stacks of food boxes are together and no two stacks of wine barrels are together.The height of a stack is defined as the number of items in the stack. Two stacks are considered different if either their heights are different or one of them contains food and other contains wine.Jon Snow doesn't like an arrangement if any stack of wine barrels has height less than or equal to h. What is the probability that Jon Snow will like the arrangement if all arrangement are equiprobably?Two arrangement of stacks are considered different if exists such i, that i-th stack of one arrangement is different from the i-th stack of the other arrangement.

The first line of input contains three integers f, w, h (0 ≤ f, w, h ≤ 105) — number of food boxes, number of wine barrels and h is as described above. It is guaranteed that he has at least one food box or at least one wine barrel.

Output the probability that Jon Snow will like the arrangement. The probability is of the form , then you need to output a single integer p·q - 1 mod (109 + 7).

NoteIn the first example f  =  1, w = 1 and h = 1, there are only two possible arrangement of stacks and Jon Snow doesn't like any of them.In the second example f = 1, w = 2 and h = 1, there are three arrangements. Jon Snow likes the (1) and (3) arrangement. So the probabilty is .

import java.util.Scanner;
public class F399 {

	public static final long p = 1_000_000_007;
	public static long[] factorial;

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int food = in.nextInt();
		int wine = in.nextInt();
		int H = in.nextInt();
		in.close();

		factorial = new long[200001];
		factorial[0] = 1;
		for(int i = 1; i < factorial.length; i++)
			factorial[i] = (factorial[i-1] * i) % p;

		long result = answer(food, wine, H);
		System.out.println(result);
	}

	public static long answer(int food, int wine, int H) {
		if(food == 0)
			return wine > H? 1 : 0;
		if(wine == 0)
			return 1;

		long[] foodArr = new long[1 + Math.max(food, wine)];
		long[] wineArr = new long[1 + Math.max(food, wine)];

		for(int i = 1; i < food+1; i++) {
			foodArr[i] = nCr(food - 1, i - 1);
		}

		for(int i = 1; i < wine+1; i++) {
			wineArr[i] = nCr(wine - 1, i - 1);
		}

		long denom = 0;
		for(int i = 1; i < foodArr.length; i++) {
			denom += 2 * wineArr[i] * foodArr[i];
			denom %= p;
		}

		for(int i = 1; i < foodArr.length-1; i++) {
			denom += foodArr[i] * wineArr[i+1];
			denom += wineArr[i] * foodArr[i+1];
			denom %= p;
		}

		long[] validWine = new long[wineArr.length];
		for(int i = 1; i < validWine.length && wine+i-1-i*(H+1) >= 0; i++) {
			validWine[i] = nCr(wine + i - 1 - i*(H+1), i-1);
		}

		long numer = 0;
		for(int i = 1; i < foodArr.length; i++) {
			numer += 2 * validWine[i] * foodArr[i];
			numer %= p;
		}

		for(int i = 1; i < foodArr.length-1; i++) {
			numer += foodArr[i] * validWine[i+1];
			numer += validWine[i] * foodArr[i+1];
			numer %= p;
		}

		long denomInv = modInverse(denom, p);
		long result = numer * denomInv % p;

		return result;
	}

	public static long nCr(int N, int R) {
		if(N == 0 && R == 0) return 1;
		if(N < 0) return 0;
		if(N < R) return 0;

		long result = factorial[N];
		long denom1 = modInverse(factorial[R], p);
		long denom2 = modInverse(factorial[N-R], p);

		result = (result * denom1) % p;
		result = (result * denom2) % p;

		return result;
	}

	//Extended Euclidean algorithm find x such that ax = 1 (mod m)
	public static long modInverse(long a, long m) {
		long[] a1 = {a, 1, 0};
		long[] b1 = {m, 0, 1};
		while(b1[0] != 0) {
			long[] c1 = new long[3];
			long q = a1[0] / b1[0];
			c1[0] = a1[0] - q * b1[0];
			c1[1] = a1[1] - q * b1[1];
			c1[2] = a1[2] - q * b1[2];
			a1 = b1;
			b1 = c1;
		}

		if(a1[1] < 0) a1[1] += m;
		return a1[1];
	}

}
/*
1 1 1
outputCopy
0
inputCopy
1 2 1
outputCopy
666666672

4138 4245 30
105072868

100000 100000 100000
0
*/

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 29);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            FBarrelsAndBoxes solver = new FBarrelsAndBoxes();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class FBarrelsAndBoxes {
        Modular mod = new Modular(1e9 + 7);
        int modVal = mod.getMod();
        Combination comb = new Combination(1000000, new Power(mod));

        public void solve(int testNumber, FastInput in, FastOutput out) {
            try {
                solve0(testNumber, in, out);
            } catch (IllegalArgumentException e) {
                out.println(0);
            }
        }

        public void solve0(int testNumber, FastInput in, FastOutput out) {
            int f = in.readInt();
            int w = in.readInt();
            int h = in.readInt();

            int threshold = f + w;

            long total = 0;
            long satisfy = 0;

            //food first
            for (int i = 1; i <= threshold; i++) {
                int forFood = DigitUtils.ceilDiv(i, 2);
                int forWine = i - forFood;
                //alloc
                total += way(forFood, f, 1) * way(forWine, w, 1) % modVal;
                satisfy += way(forFood, f, 1) * way(forWine, w, h + 1) % modVal;
            }

            for (int i = 1; i <= threshold; i++) {
                int forWine = DigitUtils.ceilDiv(i, 2);
                int forFood = i - forWine;

                //alloc
                total += way(forFood, f, 1) * way(forWine, w, 1) % modVal;
                satisfy += way(forFood, f, 1) * way(forWine, w, h + 1) % modVal;
            }

            total %= modVal;
            satisfy %= modVal;

            Power power = new Power(mod);
            long ans = satisfy * power.inverse((int) total) % modVal;
            out.println(ans);
        }

        public long way(int n, int m, int k) {
            if (n == 0) {
                return (long) m * k == 0 ? 1 : 0;
            }
            if ((long) k * n > m) {
                return 0;
            }
            m -= n * k;
            return comb.combination(m + n - 1, m);
        }

    }

    static class IntExtGCDObject {
        private int[] xy = new int[2];

        public int extgcd(int a, int b) {
            return ExtGCD.extGCD(a, b, xy);
        }

        public int getX() {
            return xy[0];
        }

    }

    static class DigitUtils {
        private DigitUtils() {
        }

        public static int floorDiv(int a, int b) {
            return a < 0 ? -ceilDiv(-a, b) : a / b;
        }

        public static int ceilDiv(int a, int b) {
            if (a < 0) {
                return -floorDiv(-a, b);
            }
            int c = a / b;
            if (c * b < a) {
                return c + 1;
            }
            return c;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class SequenceUtils {
        public static void swap(int[] data, int i, int j) {
            int tmp = data[i];
            data[i] = data[j];
            data[j] = tmp;
        }

    }

    static class Combination implements IntCombination {
        final Factorial factorial;
        int modVal;

        public Combination(Factorial factorial) {
            this.factorial = factorial;
            this.modVal = factorial.getMod().getMod();
        }

        public Combination(int limit, Power pow) {
            this(new Factorial(limit, pow));
        }

        public int combination(int m, int n) {
            if (n > m || n < 0) {
                return 0;
            }
            return (int) ((long) factorial.fact(m) * factorial.invFact(n) % modVal * factorial.invFact(m - n) % modVal);
        }

    }

    static class Power implements InverseNumber {
        static IntExtGCDObject extGCD = new IntExtGCDObject();
        final Modular modular;
        int modVal;

        public Modular getModular() {
            return modular;
        }

        public Power(Modular modular) {
            this.modular = modular;
            this.modVal = modular.getMod();
        }

        public int inverse(int x) {
            int ans = inverseExtGCD(x);
//        if(modular.mul(ans, x) != 1){
//            throw new IllegalStateException();
//        }
            return ans;
        }

        public int inverseExtGCD(int x) {
            if (extGCD.extgcd(x, modVal) != 1) {
                throw new IllegalArgumentException();
            }
            return modular.valueOf(extGCD.getX());
        }

    }

    static class ExtGCD {
        public static int extGCD(int a, int b, int[] xy) {
            if (a >= b) {
                return extGCD0(a, b, xy);
            }
            int ans = extGCD0(b, a, xy);
            SequenceUtils.swap(xy, 0, 1);
            return ans;
        }

        private static int extGCD0(int a, int b, int[] xy) {
            if (b == 0) {
                xy[0] = 1;
                xy[1] = 0;
                return a;
            }
            int ans = extGCD0(b, a % b, xy);
            int x = xy[0];
            int y = xy[1];
            xy[0] = y;
            xy[1] = x - a / b * y;
            return ans;
        }

    }

    static class Factorial {
        int[] fact;
        int[] inv;
        Modular mod;

        public Modular getMod() {
            return mod;
        }

        public Factorial(int[] fact, int[] inv, Power pow) {
            this.mod = pow.getModular();
            this.fact = fact;
            this.inv = inv;
            fact[0] = inv[0] = 1;
            int n = Math.min(fact.length, pow.getModular().getMod());
            for (int i = 1; i < n; i++) {
                fact[i] = i;
                fact[i] = mod.mul(fact[i], fact[i - 1]);
            }
            inv[n - 1] = pow.inverse(fact[n - 1]);
            for (int i = n - 2; i >= 1; i--) {
                inv[i] = mod.mul(inv[i + 1], i + 1);
            }
        }

        public Factorial(int limit, Power pow) {
            this(new int[limit + 1], new int[limit + 1], pow);
        }

        public int fact(int n) {
            return fact[n];
        }

        public int invFact(int n) {
            return inv[n];
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput append(int c) {
            cache.append(c);
            return this;
        }

        public FastOutput append(long c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(int c) {
            return append(c).println();
        }

        public FastOutput println(long c) {
            return append(c).println();
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static interface InverseNumber {
    }

    static class Modular {
        int m;

        public int getMod() {
            return m;
        }

        public Modular(int m) {
            this.m = m;
        }

        public Modular(long m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public Modular(double m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public int valueOf(int x) {
            x %= m;
            if (x < 0) {
                x += m;
            }
            return x;
        }

        public int valueOf(long x) {
            x %= m;
            if (x < 0) {
                x += m;
            }
            return (int) x;
        }

        public int mul(int x, int y) {
            return valueOf((long) x * y);
        }

        public String toString() {
            return "mod " + m;
        }

    }

    static interface IntCombination {
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskF solver = new TaskF();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskF {
        int f;
        int w;
        int h;
        final int mod = (int) (1e9 + 7);
        long[] fact = IntegerUtils.generateFactorial((int) (1e5 + 5), mod);
        long[] revFact = IntegerUtils.generateReverseFactorials((int) (1e5 + 5), mod);

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            f = in.readInt();
            w = in.readInt();
            h = in.readInt();

            if (f == 0 || w == 0) {
                out.printLine(w != 0 && w <= h ? 0 : 1);
                return;
            }

            long p = 0;
            for (int cw = 1; cw <= w && 0 <= w - cw * (h + 1); cw++) {
                int rem = w - cw * (h + 1);
                for (int cf = Math.max(cw - 1, 1); cf <= Math.min(f, cw + 1); cf++) {
                    long cur = f(cw, rem) * f(cf, f - cf) % mod;
                    p += cur;
                    if (cw == cf) {
                        p += cur;
                    }
                    p %= mod;
                }
            }

            long q = 0;
            for (int cw = 1; cw <= w; cw++) {
                for (int cf = Math.max(cw - 1, 1); cf <= Math.min(f, cw + 1); cf++) {
                    long cur = f(cw, w - cw) * f(cf, f - cf) % mod;
                    q += cur;
                    if (cw == cf) {
                        q += cur;
                    }
                    q %= mod;
//                out.printLine(cw, cf, cur, q);
                }
            }
//        out.printLine(p + "/" + q);
            out.printLine(p * IntegerUtils.reverse(q, mod) % mod);
        }

        private long f(int n, int s) {
            return comb(n - 1, s + n - 1);
        }

        private long comb(int m, int n) {
            return fact[n] * revFact[m] % mod * revFact[n - m] % mod;
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void printLine(long i) {
            writer.println(i);
        }

        public void printLine(int i) {
            writer.println(i);
        }

    }

    static class IntegerUtils {
        public static long power(long base, long exponent, long mod) {
            if (base >= mod) {
                base %= mod;
            }
            if (exponent == 0) {
                return 1 % mod;
            }
            long result = power(base, exponent >> 1, mod);
            result = result * result % mod;
            if ((exponent & 1) != 0) {
                result = result * base % mod;
            }
            return result;
        }

        public static long[] generateFactorial(int count, long module) {
            long[] result = new long[count];
            if (module == -1) {
                if (count != 0) {
                    result[0] = 1;
                }
                for (int i = 1; i < count; i++) {
                    result[i] = result[i - 1] * i;
                }
            } else {
                if (count != 0) {
                    result[0] = 1 % module;
                }
                for (int i = 1; i < count; i++) {
                    result[i] = (result[i - 1] * i) % module;
                }
            }
            return result;
        }

        public static long reverse(long number, long module) {
            return power(number, module - 2, module);
        }

        public static long[] generateReverse(int upTo, long module) {
            long[] result = new long[upTo];
            if (upTo > 1) {
                result[1] = 1;
            }
            for (int i = 2; i < upTo; i++) {
                result[i] = (module - module / i * result[((int) (module % i))] % module) % module;
            }
            return result;
        }

        public static long[] generateReverseFactorials(int upTo, long module) {
            long[] result = generateReverse(upTo, module);
            if (upTo > 0) {
                result[0] = 1;
            }
            for (int i = 1; i < upTo; i++) {
                result[i] = result[i] * result[i - 1] % module;
            }
            return result;
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

/**
 * @author Don Li
 */
public class BarrelsBoxes2 {

    int N = (int) 1e6 + 5;
    int MOD = (int) 1e9 + 7;

    long[] inv = new long[N];
    long[] fac = new long[N];
    long[] ifac = new long[N];

    {
        inv[1] = 1;
        for (int i = 2; i < N; i++) inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;

        fac[0] = fac[1] = 1;
        ifac[0] = ifac[1] = 1;
        for (int i = 2; i < N; i++) {
            fac[i] = fac[i - 1] * i % MOD;
            ifac[i] = ifac[i - 1] * inv[i] % MOD;
        }
    }

    void solve() {
        int f = in.nextInt(), w = in.nextInt(), h = in.nextInt();

        long res = 0, tot = bc(f + w, w);
        for (int n = 0; n <= f + 1 && w >= (long) (h + 1) * n; n++) {
            res = (res + bc(f + 1, n) * ways(w - (h + 1) * n, n) % MOD) % MOD;
        }

        long ans = res * inverse(tot) % MOD;
        out.println(ans);
    }

    long ways(int n, int m) {
        if (n == 0 && m == 0) return 1;
        if (n == 0) return 1;
        if (m == 0) return 0;
        return bc(n + m - 1, m - 1);
    }

    long bc(int n, int k) {
        if (n < k) return 0;
        if (n < 0 || k < 0) return 0;
        return fac[n] * ifac[k] % MOD * ifac[n - k] % MOD;
    }

    long inverse(long i) {
        return mpow(i, MOD - 2);
    }

    long mpow(long a, long n) {
        long res = 1;
        while (n > 0) {
            if ((n & 1) > 0) res = res * a % MOD;
            a = a * a % MOD;
            n >>= 1;
        }
        return res;
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new BarrelsBoxes2().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

        public String nextToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(in.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(nextToken());
        }

        public long nextLong() {
            return Long.parseLong(nextToken());
        }

        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

/**
 * @author Don Li
 */
public class BarrelsBoxes {

    int N = (int) 1e6 + 5;
    int MOD = (int) 1e9 + 7;

    long[] inv = new long[N];
    long[] fac = new long[N];
    long[] ifac = new long[N];

    void solve() {
        int f = in.nextInt(), w = in.nextInt(), h = in.nextInt();

        inv[1] = 1;
        for (int i = 2; i < N; i++) inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;

        fac[0] = fac[1] = 1;
        ifac[0] = ifac[1] = 1;
        for (int i = 2; i < N; i++) {
            fac[i] = fac[i - 1] * i % MOD;
            ifac[i] = ifac[i - 1] * inv[i] % MOD;
        }

        int max = Math.min(f + w, 2 * Math.min(f, w) + 1);

        long res = 0, tot = 0;
        for (int n = 1; n <= max; n++) {
            int x = (n + 1) / 2, y = n / 2;
            if (f >= x && w >= y) {
                tot = (tot + ways1(w, y) * ways1(f, x) % MOD) % MOD;
                if (w >= (long) (h + 1) * y) {
                    int b = w - (h + 1) * y;
                    res = (res + ways2(b, y) * ways1(f, x) % MOD) % MOD;
                }
            }
            if (f >= y && w >= x) {
                tot = (tot + ways1(w, x) * ways1(f, y) % MOD) % MOD;
                if (w >= (long) (h + 1) * x) {
                    int b = w - (h + 1) * x;
                    res = (res + ways2(b, x) * ways1(f, y) % MOD) % MOD;
                }
            }
        }

        long ans = res * inverse(tot) % MOD;
        out.println(ans);
    }

    long ways1(int n, int m) {
        if (n == 0 && m == 0) return 1;
        if (n == 0) return 0;
        if (m == 0) return 0;
        return bc(n - 1, m - 1);
    }

    long ways2(int n, int m) {
        if (n == 0 && m == 0) return 1;
        if (n == 0) return 1;
        if (m == 0) return 0;
        return bc(n + m - 1, m - 1);
    }

    long bc(int n, int k) {
        if (n < k) return 0;
        if (n < 0 || k < 0) return 0;
        return fac[n] * ifac[k] % MOD * ifac[n - k] % MOD;
    }

    long inverse(long i) {
        return mpow(i, MOD - 2);
    }

    long mpow(long a, long n) {
        long res = 1;
        while (n > 0) {
            if ((n & 1) > 0) res = res * a % MOD;
            a = a * a % MOD;
            n >>= 1;
        }
        return res;
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new BarrelsBoxes().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

        public String nextToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(in.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(nextToken());
        }

        public long nextLong() {
            return Long.parseLong(nextToken());
        }

        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}

/**
 * @author derrick20
 */

import java.io.*;
import java.util.*;

public class BarrelsBoxes {
    public static void main(String[] args) throws Exception {
        FastScanner sc = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);

        int F = sc.nextInt();
        int W = sc.nextInt();
        int H = sc.nextInt();
        if (W == 0) {
            // we can't count anything, since no stacks will ever have any condition
            // to be applied. If there are wines, then we CAN count it correctly
            out.println(1);
        } else {
            int MAX = (int) 1e5 + 1; // todo change this!
            fact = new long[MAX + 1];
            invFact = new long[MAX + 1];
            fact[0] = 1;
            invFact[0] = 1;
            for (int i = 1; i <= MAX; i++) {
                fact[i] = ((long) i * fact[i - 1]) % mod;
                invFact[i] = inv(fact[i]);
            }

            long good = 0;
            for (int k = 1; W - k * (H + 1) >= 0 && F >= k - 1; k++) {
                long amt = (choose(W - k * (H + 1) + k - 1, k - 1) * choose(F + 1, k)) % mod;
                good = (good + amt) % mod;
            }
            long total = 0;
            for (int k = 1; W - k >= 0 && F >= k - 1; k++) {
                long amt = (choose(W - 1, k - 1) * choose(F + 1, k)) % mod;
                total = (total + amt) % mod;
            }
            long prob = (good * inv(total)) % mod;
            out.println(prob);
        }
        out.close();
    }

    // todo SET THE MOD
    static long mod = (long) 1e9 + 7;
    static long[] fact, invFact;

    static long choose(int n, int k) {
        ASSERT(k <= n, "Invalid choose");
        long ans = (fact[n] * invFact[n - k]) % mod;
        return (ans * invFact[k]) % mod;
    }

    static long inv(long x) {
        return fastExpo(x, mod - 2);
    }

    static long fastExpo(long x, long k) {
        long ans = 1;
        long bit = x;
        while (k > 0) {
            if (k % 2 == 1) {
                ans = (bit * ans) % mod;
            }
            bit = (bit * bit) % mod;
            k /= 2;
        }
        return ans;
    }

    static class FastScanner {
        private int BS = 1 << 16;
        private char NC = (char) 0;
        private byte[] buf = new byte[BS];
        private int bId = 0, size = 0;
        private char c = NC;
        private double cnt = 1;
        private BufferedInputStream in;

        public FastScanner() {
            in = new BufferedInputStream(System.in, BS);
        }

        public FastScanner(String s) {
            try {
                in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
            } catch (Exception e) {
                in = new BufferedInputStream(System.in, BS);
            }
        }

        private char getChar() {
            while (bId == size) {
                try {
                    size = in.read(buf);
                } catch (Exception e) {
                    return NC;
                }
                if (size == -1) return NC;
                bId = 0;
            }
            return (char) buf[bId++];
        }

        public int nextInt() {
            return (int) nextLong();
        }

        public int[] nextInts(int N) {
            int[] res = new int[N];
            for (int i = 0; i < N; i++) {
                res[i] = (int) nextLong();
            }
            return res;
        }

        public long[] nextLongs(int N) {
            long[] res = new long[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextLong();
            }
            return res;
        }

        public long nextLong() {
            cnt = 1;
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            long res = 0;
            for (; c >= '0' && c <= '9'; c = getChar()) {
                res = (res << 3) + (res << 1) + c - '0';
                cnt *= 10;
            }
            return neg ? -res : res;
        }

        public double nextDouble() {
            double cur = nextLong();
            return c != '.' ? cur : cur + nextLong() / cnt;
        }

        public double[] nextDoubles(int N) {
            double[] res = new double[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextDouble();
            }
            return res;
        }

        public String next() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c > 32) {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public String nextLine() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c != '\n') {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public boolean hasNext() {
            if (c > 32) return true;
            while (true) {
                c = getChar();
                if (c == NC) return false;
                else if (c > 32) return true;
            }
        }
    }

    static void ASSERT(boolean assertion, String message) {
        if (!assertion) throw new AssertionError(message);
    }
}

// practice with rainboy
import java.io.*;
import java.util.*;

public class CF768F extends PrintWriter {
	CF768F() { super(System.out, true); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF768F o = new CF768F(); o.main(); o.flush();
	}

	static final int MD = 1000000007;
	int d_, x_, y_;
	void gcd_(int a, int b) {
		if (b == 0) {
			d_ = a;
			x_ = 1; y_ = 0;
		} else {
			gcd_(b, a % b);
			int tmp = x_ - a / b * y_; x_ = y_; y_ = tmp;
		}
	}
	int inv(int a, int b) {
		gcd_(a, b);
		return x_;
	}
	int[] ff, gg;
	void init(int n) {
		ff = new int[n];
		gg = new int[n];
		for (int i = 0, f = 1; i < n; i++) {
			gg[i] = inv(ff[i] = f, MD);
			f = (int) ((long) f * (i + 1) % MD);
		}
	}
	int choose(int n, int k) {
		return n < k ? 0 : (int) ((long) ff[n] * gg[k] % MD * gg[n - k] % MD);
	}
	void main() {
		int f = sc.nextInt();
		int w = sc.nextInt();
		int h = sc.nextInt();
		if (f == 0) {
			println(w > h ? 1 : 0);
			return;
		}
		if (w == 0) {
			println(1);
			return;
		}
		int n = Math.max(f, w);
		init(n);
		int[] aa = new int[n + 2];
		for (int i = 1; i <= f; i++)
			aa[i] = choose(f - 1, i - 1);
		int[] bb = new int[n + 2];
		for (int j = 1; j <= w; j++)
			bb[j] = choose(w - 1, j - 1);
		int[] cc = new int[n + 2];
		for (int j = 1; (h + 1) * j <= w; j++)
			cc[j] = choose(w - h * j - 1, j - 1);
		int p = 0, q = 0;
		for (int i = 1; i <= n; i++) {
			p = (int) ((p + aa[i] * (cc[i] * 2L + cc[i - 1] + cc[i + 1])) % MD);
			q = (int) ((q + aa[i] * (bb[i] * 2L + bb[i - 1] + bb[i + 1])) % MD);
		}
		if (p < 0)
			p += MD;
		if (q < 0)
			q += MD;
		int ans = (int) ((long) p * inv(q, MD) % MD);
		if (ans < 0)
			ans += MD;
		println(ans);
	}
}

import java.io.*;
import java.util.*;

public class R399qF {

  static int mod = (int)1e9 + 7;
  static long fact[], inv[];

  public static void main(String[] args) {
    InputReader in = new InputReader(System.in);
    PrintWriter out = new PrintWriter(System.out);

    pre();

    int f = in.nextInt();
    int w = in.nextInt();
    int h = in.nextInt();

    long p = 0;
    long q = 0;

    for (int n = 1; n <= f + w; n++) {
      {
        int F = (n + 1) / 2;
        int W = n / 2;
        q += get(f, F, 1) * get(w, W, 1);
        p += get(f, F, 1) * get(w, W, h + 1);
      }
      {
        int F = n / 2;
        int W = (n + 1) / 2;
        q += get(f, F, 1) * get(w, W, 1);
        p += get(f, F, 1) * get(w, W, h + 1);
      }
      p %= mod;
      q %= mod;
    }

    out.println((p * pow(q, mod - 2,mod)) % mod);
    out.close();
  }

  static long get(long balls, long bins, long min) {
    if (bins == 0) {
      return balls == 0 ? 1 : 0;
    }
    return getSol(balls - bins * min, bins);
  }

  static long getSol(long balls, long bins) {
    if (balls < 0)
      return 0;
    return C((int)(balls + bins - 1), (int)(bins - 1));
  }

  static long C(int N, int R) {
    if (R < 0 || R > N)
      return 0;
    long t = (fact[N] * inv[R]) % mod;
    return (t * inv[N - R]) % mod;
  }

  static void pre() {
    int N = 8 * 100010;
    fact = new long[N];
    inv = new long[N];

    fact[0] = 1;
    inv[0] = pow(fact[0], mod - 2, mod);

    for (int i = 1; i < N; i++) {
      fact[i] = (i * fact[i - 1]) % mod;
      inv[i] = pow(fact[i], mod - 2, mod);
    }
  }

  static long pow(long a, int b, int mod) {
    if (b == 0) {
      return 1;
    }
    long t = pow(a, b / 2, mod);
    t = (t * t) % mod;
    if ( b % 2 == 1) {
      t = (t * a) % mod;
    }
    return t;
  }

  static class InputReader {

    private final InputStream stream;
    private final byte[] buf = new byte[8192];
    private int curChar, snumChars;

    public InputReader(InputStream st) {
      this.stream = st;
    }

    public int read() {
      if (snumChars == -1)
        throw new InputMismatchException();
      if (curChar >= snumChars) {
        curChar = 0;
        try {
          snumChars = stream.read(buf);
        } catch (IOException e) {
          throw new InputMismatchException();
        }
        if (snumChars <= 0)
          return -1;
      }
      return buf[curChar++];
    }

    public int nextInt() {
      int c = read();
      while (isSpaceChar(c)) {
        c = read();
      }
      int sgn = 1;
      if (c == '-') {
        sgn = -1;
        c = read();
      }
      int res = 0;
      do {
        res *= 10;
        res += c - '0';
        c = read();
      } while (!isSpaceChar(c));
      return res * sgn;
    }

    public long nextLong() {
      int c = read();
      while (isSpaceChar(c)) {
        c = read();
      }
      int sgn = 1;
      if (c == '-') {
        sgn = -1;
        c = read();
      }
      long res = 0;
      do {
        res *= 10;
        res += c - '0';
        c = read();
      } while (!isSpaceChar(c));
      return res * sgn;
    }

    public int[] nextIntArray(int n) {
      int a[] = new int[n];
      for (int i = 0; i < n; i++) {
        a[i] = nextInt();
      }
      return a;
    }

    public String readString() {
      int c = read();
      while (isSpaceChar(c)) {
        c = read();
      }
      StringBuilder res = new StringBuilder();
      do {
        res.appendCodePoint(c);
        c = read();
      } while (!isSpaceChar(c));
      return res.toString();
    }

    public String nextLine() {
      int c = read();
      while (isSpaceChar(c))
        c = read();
      StringBuilder res = new StringBuilder();
      do {
        res.appendCodePoint(c);
        c = read();
      } while (!isEndOfLine(c));
      return res.toString();
    }

    public boolean isSpaceChar(int c) {
      return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    private boolean isEndOfLine(int c) {
      return c == '\n' || c == '\r' || c == -1;
    }

  }

}

import java.util.*;
import java.io.*;

public class BarrelBox {
    static long f[] = new long [400010];
    final static int mod = 1000000000 + 7;
    static long bigmod(long a, long b) {
        if(b == 0) return 1;
        if((b & 1) == 1) return (bigmod(a, b - 1) * a) % mod;
        long m = bigmod(a, b >> 1);
        return (m * m) % mod;
    }
    static long inverse(long a) {
        return bigmod(a, mod - 2);
    }
    static long nCr(int n, int r) {
        if(n < 0 || r < 0) return 0;
        if(n < r) return 0;
        long num = f[n];
        long den = (f[r] * f[n - r]) % mod;
        return (num * inverse(den)) % mod;
    }
    static long junk(int n, int k) {
        return nCr(n - 1, k - 1);
    }
    public static void main(String [] args) {
        Reader in = new Reader ();
        f[0] = 1;
        for(int i = 1; i <= 400000; i++) {
            f[i] = f[i - 1] * i;
            f[i] %= mod;
        }

        int f = in.nextInt();
        int w = in.nextInt();
        int h = in.nextInt();

        if(f == 0) {
            if(w > h) System.out.println(1);
            else System.out.println(0);
            System.exit(0);
        }
        if(w == 0) {
            System.out.println(1);
            System.exit(0);
        }

        long p = 0;
        for(int i = 1; i <= w; i++) {
            int x = w - (i * h);
            if(x < 0) break;
            long ways = junk(x, i);
            p += ways * junk(f, i + 1);
            p %= mod;
            p += ways * junk(f, i) * 2;
            p %= mod;
            p += ways * junk(f, i - 1);
            p %= mod;
        }

        long q = 0;
        for(int i = 1; i <= w; i++) {
            long ways = junk(w, i);
            q += ways * junk(f, i + 1);
            q %= mod;
            q += ways * junk(f, i) * 2;
            q %= mod;
            q += ways * junk(f, i - 1);
            q %= mod;
        }
        long ans = p * inverse(q);
        System.out.println(ans % mod);
    }
    static class Reader {
        private StringTokenizer a;
        private BufferedReader b;
        Reader () {
            a = null;
            b = new BufferedReader (new InputStreamReader (System.in));
        }
        public String next () {
            while(a == null || !a.hasMoreTokens()) {
                try {
                    a = new StringTokenizer (b.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return a.nextToken();
        }
        public int nextInt() {
            return Integer.parseInt(this.next());
        }
        public long nextLong () {
            return Long.parseLong(this.next());
        }
        public double nextDouble () {
            return Double.parseDouble(this.next());
        }
        public String nextLine() {
            try {
                return b.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }
    }
    static class Writer {
        private PrintWriter a;
        private StringBuffer b;
        Writer () {
            a = new PrintWriter (System.out);
            b = new StringBuffer ("");
        }
        public void write (Object s) {
            b.append(s);
        }
        public void writeln(Object s) {
            b.append(s).append('\n');
        }
        public void flush () {
            a.print(b);
            a.flush();
            a.close();
        }
    }
}

import static java.lang.Double.parseDouble;
import static java.lang.Integer.parseInt;
import static java.lang.Long.parseLong;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.System.exit;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.StringTokenizer;

public class F {

	static BufferedReader in;
	static PrintWriter out;
	static StringTokenizer tok;

	static final int MOD = 1000000007;

	static int add(int a, int b) {
		int res = a + b;
		return res >= MOD ? res - MOD : res;
	}

	static int sub(int a, int b) {
		int res = a - b;
		return res < 0 ? res + MOD : res;
	}

	static int mul(int a, int b) {
		int res = (int) ((long) a * b % MOD);
		return res < 0 ? res + MOD : res;
	}

	static int inv(int a) {
		return BigInteger.valueOf(a).modInverse(BigInteger.valueOf(MOD)).intValue();
	}

	static void solve() throws Exception {
		int f = nextInt();
		int w = nextInt();
		int h = nextInt();
		int facts[] = new int[max(f, w) + 1];
		facts[0] = 1;
		for (int i = 1; i < facts.length; i++) {
			facts[i] = mul(facts[i - 1], i);
		}
		int totalNum = 0, totalDen = 1, goodNum = 0, goodDen = 1;
		for (int cntF = 0; cntF <= f; cntF++) {
			if ((f == 0) != (cntF == 0)) {
				continue;
			}
			int curNum, curDen;
			if (f == 0) {
				curNum = curDen = 1;
			} else {
				curNum = facts[f - 1];
				curDen = mul(facts[cntF - 1], facts[f - cntF]);
			}
			for (int cntW = max(cntF - 1, 0); cntW <= min(cntF + 1, w); cntW++) {
				if ((w == 0) != (cntW == 0)) {
					continue;
				}
				int curNum2, curDen2;
				if (w == 0) {
					curNum2 = curNum;
					curDen2 = curDen;
				} else {
					curNum2 = mul(curNum, facts[w - 1]);
					curDen2 = mul(curDen, mul(facts[cntW - 1], facts[w - cntW]));
				}
				if (cntF == cntW) {
					curNum2 = add(curNum2, curNum2);
				}
				totalNum = add(mul(totalNum, curDen2), mul(totalDen, curNum2));
				totalDen = mul(totalDen, curDen2);
				if (w == 0) {
					goodNum = add(mul(goodNum, curDen2), mul(goodDen, curNum2));
					goodDen = mul(goodDen, curDen2);
				} else if ((long) cntW * (h + 1) <= w) {
					curNum2 = mul(curNum, facts[w - cntW * h - 1]);
					curDen2 = mul(curDen, mul(facts[cntW - 1], facts[w - cntW * (h + 1)]));
					if (cntF == cntW) {
						curNum2 = add(curNum2, curNum2);
					}
					goodNum = add(mul(goodNum, curDen2), mul(goodDen, curNum2));
					goodDen = mul(goodDen, curDen2);
				}
			}
		}
		out.print(mul(mul(goodNum, totalDen), inv(mul(goodDen, totalNum))));
	}

	static int nextInt() throws IOException {
		return parseInt(next());
	}

	static long nextLong() throws IOException {
		return parseLong(next());
	}

	static double nextDouble() throws IOException {
		return parseDouble(next());
	}

	static String next() throws IOException {
		while (tok == null || !tok.hasMoreTokens()) {
			tok = new StringTokenizer(in.readLine());
		}
		return tok.nextToken();
	}

	public static void main(String[] args) {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(new OutputStreamWriter(System.out));
			solve();
			in.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			exit(1);
		}
	}
}

import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

public class Template implements Runnable {

    BufferedReader in;
    PrintWriter out;
    StringTokenizer tok = new StringTokenizer("");

    void init() throws FileNotFoundException {
        try {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        } catch (Exception e) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        }
    }

    String readString() throws IOException {
        while (!tok.hasMoreTokens()) {
            try {
                tok = new StringTokenizer(in.readLine());
            } catch (Exception e) {
                return null;
            }
        }
        return tok.nextToken();
    }

    int readInt() throws IOException {
        return Integer.parseInt(readString());
    }

    int[] readIntArray(int size) throws IOException {
        int[] res = new int[size];
        for (int i = 0; i < size; i++) {
            res[i] = readInt();
        }
        return res;
    }

    long readLong() throws IOException {
        return Long.parseLong(readString());
    }

    double readDouble() throws IOException {
        return Double.parseDouble(readString());
    }

    <T> List<T>[] createGraphList(int size) {
        List<T>[] list = new List[size];
        for (int i = 0; i < size; i++) {
            list[i] = new ArrayList<>();
        }
        return list;
    }

    public static void main(String[] args) {
        new Template().run();
        // new Thread(null, new Template(), "", 1l * 200 * 1024 * 1024).start();
    }

    long timeBegin, timeEnd;

    void time() {
        timeEnd = System.currentTimeMillis();
        System.err.println("Time = " + (timeEnd - timeBegin));
    }

    long memoryTotal, memoryFree;

    void memory() {
        memoryFree = Runtime.getRuntime().freeMemory();
        System.err.println("Memory = " + ((memoryTotal - memoryFree) >> 10)
                + " KB");
    }

    public void run() {
        try {
            timeBegin = System.currentTimeMillis();
            memoryTotal = Runtime.getRuntime().freeMemory();
            init();
            solve();
            out.close();
            if (System.getProperty("ONLINE_JUDGE") == null) {
                time();
                memory();
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }

    long[] fact;
    long[] revfact;
    int mod = (int) 1e9 + 7;

    long binpow(long x, int p, int mod) {
        if (p == 0) {
            return 1 % mod;
        }
        if (p % 2 == 0) {
            long half = binpow(x, p / 2, mod);
            return half * half % mod;
        } else {
            return x * binpow(x, p - 1, mod) % mod;
        }
    }

    long C(int n, int k) {
        if (k > n) return 0;
        long answer = fact[n];
        answer = answer * revfact[n - k] % mod;
        answer = answer * revfact[k] % mod;
        return answer;
    }

    long ways(int columns, int count, int minHeight) {
        if (columns == 0) {
            if (count == 0) return 1;
            return 0;
        }
        if (count / minHeight < columns) return 0;
        if (columns == 1) return 1;
        int ost = count - columns * minHeight;
        //return binpow(ost + 1, columns - 1, mod);
        int n = ost;
        int m = columns;
        return C(n + m - 1, m - 1);

       // return C(ost + 1, columns - 1);

//        return binpow(columns, ost, mod);
    }

    void solve() throws IOException {
        int MAX = 2 * 100000 + 100;
        fact = new long[MAX];
        revfact = new long[MAX];
        fact[0] = revfact[0] = 1;
        for (int i = 1; i < MAX; i++) {
            fact[i] = fact[i - 1] * i % mod;
            revfact[i] = binpow(fact[i], mod - 2, mod);
        }
        int f = readInt();
        int w = readInt();
        int h = readInt();
        if (w == 0) {
            out.println(1);
            return;
        }

        long correct = 0;
        long all = 0;

        for (int wineColumns = 1; wineColumns <= w; wineColumns++) {
            long foodCount = (ways(wineColumns - 1, f, 1) + ways(wineColumns + 1, f, 1) + ways(wineColumns, f, 1) * 2) % mod;
            all += ways(wineColumns, w, 1) * foodCount % mod;
            all %= mod;
            correct += ways(wineColumns, w, h + 1) * foodCount % mod;
            correct %= mod;
        }
        long answer = correct * binpow(all, mod - 2, mod) % mod;
        //long etalon = new NaiveSolver().solve(f, w, h);
        //if (answer != etalon) throw new RuntimeException("answer not equal etalon");
        out.println(answer);
    }

    class NaiveSolver {

        long solve(int f, int w, int h) {
            brut(f, w, h, true, true, "");
            brut(f, w, h, true, false, "");
            return correct * binpow(all, mod - 2, mod) % mod;
        }

        long correct;
        long all;

        void brut(int f, int w, int h, boolean nowAllOk, boolean nowWine, String represent) {
            if (f == 0 && w == 0) {
                all++;
                if (nowAllOk) correct++;
                System.err.println(represent);
                return;
            }
            if (nowWine) {
                if (w == 0) return;
            } else {
                if (h == 0) return;
            }
            if (nowWine) {
                for (int i = 1; i <= w; i++) {
                    brut(f, w - i, h, nowAllOk & (i > h), !nowWine, represent + str('w', i));
                }
            } else {
                for (int i = 1; i <= f; i++) {
                    brut(f - i, w, h, nowAllOk, !nowWine, represent + str('f', i));
                }
            }
        }
    }

    String str(char x, int cnt) {
        String res = "";
        while (cnt-- > 0) {
            res += x;
        }
        return res;
    }

}

// package codeforces.cf3xx.cf399;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class F {
    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);

        int f = in.nextInt();
        int w = in.nextInt();
        int h = in.nextInt();

        prec(300000);

        long ptn = 0;
        for (int pile = 1 ; pile <= f+1 ; pile++) {
            int leftW = w - (h + 1) * pile;
            if (leftW < 0) {
                break;
            }
            ptn += comb(f+1, pile) * comb(leftW+pile-1, pile-1) % MOD;
            ptn %= MOD;
        }
        long all = comb(f+w, f) % MOD;
        if (w == 0) {
            ptn = 1;
        }
        out.println(ptn * inv(all) % MOD);
        out.flush();
    }

    static final int MOD = 1000000007;

    static long pow(long a, long x) {
        long res = 1;
        while (x > 0) {
            if (x%2 != 0) {
                res = (res*a)%MOD;
            }
            a = (a*a)%MOD;
            x /= 2;
        }
        return res;
    }

    static long inv(long a) {
        return pow(a, MOD-2)%MOD;
    }

    static long[] _fact;
    static long[] _invfact;

    static long comb(long ln, long lr) {
        int n = (int) ln;
        int r = (int) lr;
        if (n < 0 || r < 0 || r > n) {
            return 0;
        }
        if (r > n/2) {
            r = n-r;
        }
        return (((_fact[n]*_invfact[n-r])%MOD)*_invfact[r])%MOD;
    }

    static void prec(int n) {
        _fact = new long[n+1];
        _invfact = new long[n+1];
        _fact[0] = 1;
        _invfact[0] = 1;
        for (int i = 1; i <= n; i++) {
            _fact[i] = _fact[i-1]*i%MOD;
            _invfact[i] = inv(_fact[i]);
        }
    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        private int[] nextInts(int n) {
            int[] ret = new int[n];
            for (int i = 0; i < n; i++) {
                ret[i] = nextInt();
            }
            return ret;
        }

        private int[][] nextIntTable(int n, int m) {
            int[][] ret = new int[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    ret[i][j] = nextInt();
                }
            }
            return ret;
        }

        private long[] nextLongs(int n) {
            long[] ret = new long[n];
            for (int i = 0; i < n; i++) {
                ret[i] = nextLong();
            }
            return ret;
        }

        private long[][] nextLongTable(int n, int m) {
            long[][] ret = new long[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    ret[i][j] = nextLong();
                }
            }
            return ret;
        }

        private double[] nextDoubles(int n) {
            double[] ret = new double[n];
            for (int i = 0; i < n; i++) {
                ret[i] = nextDouble();
            }
            return ret;
        }

        private int next() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public char nextChar() {
            int c = next();
            while (isSpaceChar(c))
                c = next();
            if ('a' <= c && c <= 'z') {
                return (char) c;
            }
            if ('A' <= c && c <= 'Z') {
                return (char) c;
            }
            throw new InputMismatchException();
        }

        public String nextToken() {
            int c = next();
            while (isSpaceChar(c))
                c = next();
            StringBuilder res = new StringBuilder();
            do {
                res.append((char) c);
                c = next();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public int nextInt() {
            int c = next();
            while (isSpaceChar(c))
                c = next();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = next();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c-'0';
                c = next();
            } while (!isSpaceChar(c));
            return res*sgn;
        }

        public long nextLong() {
            int c = next();
            while (isSpaceChar(c))
                c = next();
            long sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = next();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c-'0';
                c = next();
            } while (!isSpaceChar(c));
            return res*sgn;
        }

        public double nextDouble() {
            return Double.valueOf(nextToken());
        }

        public boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    static void debug(Object... o) {
        System.err.println(Arrays.deepToString(o));
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskF solver = new TaskF();
		solver.solve(1, in, out);
		out.close();
	}

	static class TaskF {
		int n;
		int m;
		int h;
		int good = 0;
		int total = 0;
		final int N = 200010;
		final int MOD = (int) (1e9 + 7);
		int[] fact = new int[N];
		int[] inv = new int[N];
		int[] invFact = new int[N];

		public void solve(int testNumber, FastScanner in, PrintWriter out) {
			precalc();
			n = in.nextInt();
			m = in.nextInt();
			h = in.nextInt();
			if (m == 0 || h == 0) {
				out.println(1);
				return;
			}
			for (int numStacks = 1; numStacks <= n + m; numStacks++) {
				int a = numStacks / 2;
				int b = numStacks - a;
				check(a, b);
				check(b, a);
			}
			out.println(good * (long) inv(total) % MOD);
		}

		private void check(int a, int b) {
			total = (int) ((total + (long) f(n - a, a) * f(m - b, b)) % MOD);
			if ((long) m - b * (long) (h + 1) < 0) {
				return;
			}
			good = (int) ((good + (long) f(n - a, a) * f(m - b * (h + 1), b)) % MOD);
		}

		private int f(int n, int k) {
			if (n < 0 || k < 0) {
				return 0;
			}
			return C(n + k - 1, k - 1);
		}

		private void precalc() {
			inv[1] = 1;
			for (int i = 2; i < N; i++) {
				inv[i] = (int) ((MOD - (MOD / i) * (long) inv[MOD % i] % MOD) % MOD);
			}
			fact[0] = 1;
			invFact[0] = 1;
			for (int i = 1; i < N; i++) {
				fact[i] = (int) (i * (long) fact[i - 1] % MOD);
				invFact[i] = (int) (inv[i] * (long) invFact[i - 1] % MOD);
			}
		}

		private int C(int n, int k) {
			if (k < 0 || k > n) return 0;
			long a = fact[n];
			long b = invFact[k];
			b = b * invFact[n - k] % MOD;
			return (int) (a * b % MOD);
		}

		private int inv(int x) {
			return pow(x, MOD - 2);
		}

		private int pow(long a, long n) {
			long r = 1;
			while (n > 0) {
				if (n % 2 == 1) {
					r = r * a % MOD;
				}
				a = a * a % MOD;
				n /= 2;
			}
			return (int) r;
		}

	}

	static class FastScanner {
		private BufferedReader in;
		private StringTokenizer st;

		public FastScanner(InputStream stream) {
			in = new BufferedReader(new InputStreamReader(stream));
		}

		public String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					String rl = in.readLine();
					if (rl == null) {
						return null;
					}
					st = new StringTokenizer(rl);
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

	}
}

//package round399;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class F3 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";
//	String INPUT = "1 2 1 ";
	int mod = 1000000007;
	int[][] fif = enumFIF(200005, mod);

	void solve()
	{
		int f = ni(), w = ni(), h = ni();
		if(f == 0){
			if(w <= h){
				out.println(0);
			}else{
				out.println(1);
			}
			return;
		}
		if(w == 0){
			out.println(1);
			return;
		}

		long[] fs = new long[100005];
		long[] ws = new long[100005];
		long[] whs = new long[100005];
		for(int i = 1;i <= 100004;i++){
			fs[i] = C(f-1, i-1, mod, fif);
			ws[i] = C(w-1, i-1, mod, fif);
			whs[i] = C(w-1-(long)i*h, i-1, mod, fif);
		}
		long Q = 0, P = 0;
		for(int i = 0;i <= 100000;i++){
			Q += fs[i]*ws[i]*2+fs[i+1]*ws[i]+fs[i]*ws[i+1];
			Q %= mod;
			P += fs[i]*whs[i]*2+fs[i+1]*whs[i]+fs[i]*whs[i+1];
			P %= mod;
		}
		long ret = P*invl(Q, mod) % mod;
		if(ret < 0)ret += mod;
		out.println(ret);
	}

	long X(int num, int place, int h)
	{
		if(num < 0)return 0;
		if(h < 0)return 0;
		if(num > (long)place*h)return 0;

		long ret = 0;
		int sgn = 1;
		for(int i = 0;num-(h+1)*i >= 0;i++, sgn = -sgn){
			ret += C(place, i, mod, fif) * C(num-(h+1)*i+place-1, place-1, mod, fif) * sgn;
			ret %= mod;
		}
		if(ret < 0)ret += mod;
		return ret;
	}

	public static long invl(long a, long mod) {
		long b = mod;
		long p = 1, q = 0;
		while (b > 0) {
			long c = a / b;
			long d;
			d = a;
			a = b;
			b = d % b;
			d = p;
			p = q;
			q = d - c * q;
		}
		return p < 0 ? p + mod : p;
	}

	public static long C(long n, int r, int mod, int[][] fif) {
		if (n < 0 || r < 0 || r > n)
			return 0;
		return (long) fif[0][(int)n] * fif[1][r] % mod * fif[1][(int)n - r] % mod;
	}

	public static int[][] enumFIF(int n, int mod) {
		int[] f = new int[n + 1];
		int[] invf = new int[n + 1];
		f[0] = 1;
		for (int i = 1; i <= n; i++) {
			f[i] = (int) ((long) f[i - 1] * i % mod);
		}
		long a = f[n];
		long b = mod;
		long p = 1, q = 0;
		while (b > 0) {
			long c = a / b;
			long d;
			d = a;
			a = b;
			b = d % b;
			d = p;
			p = q;
			q = d - c * q;
		}
		invf[n] = (int) (p < 0 ? p + mod : p);
		for (int i = n - 1; i >= 0; i--) {
			invf[i] = (int) ((long) invf[i + 1] * (i + 1) % mod);
		}
		return new int[][] { f, invf };
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new F3().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskF solver = new TaskF();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskF {
        public int mod = 1000000007;
        public long[] fact;
        public long[] ifact;

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int f = in.nextInt(), w = in.nextInt(), h = in.nextInt();
            if (w == 0) {
                out.println(1);
                return;
            }
            if (f == 0) {
                if (w > h) out.println(1);
                else out.println(0);
                return;
            }
            long[][] x = Factorials.getFIF(f + w + 1, mod);
            fact = x[0];
            ifact = x[1];
            // starts with f
            long num = 0, den = 0;
            for (int len = 1; len <= w + f; len++) {
                int needf = (len + 1) / 2;
                if (needf > f) break;
                int needw = len / 2;
                if (needw > w) break;
                long a1 = nways(f - needf, needf);
                den = (den + a1 * nways(w - needw, needw)) % mod;
                if (1L * needw * (h + 1) <= w)
                    num = (num + a1 * nways(w - needw * (h + 1), needw)) % mod;
            }
            // starts with w
            for (int len = 1; len <= w + f; len++) {
                int needw = (len + 1) / 2;
                if (needw > w) break;
                int needf = len / 2;
                if (needf > f) break;
                long a1 = nways(f - needf, needf);
                den = (den + a1 * nways(w - needw, needw)) % mod;
                if (1L * needw * (h + 1) <= w)
                    num = (num + a1 * nways(w - needw * (h + 1), needw)) % mod;
            }

            out.println(num * Utils.inv(den, mod) % mod);
        }

        public long nways(int i, int j) {
            if (i < 0) return 0;
            if (j == 0) {
                return i == 0 ? 1 : 0;
            }
            return fact[i + j - 1] * ifact[j - 1] % mod * ifact[i] % mod;
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (this.numChars == -1) {
                throw new InputMismatchException();
            } else {
                if (this.curChar >= this.numChars) {
                    this.curChar = 0;

                    try {
                        this.numChars = this.stream.read(this.buf);
                    } catch (IOException var2) {
                        throw new InputMismatchException();
                    }

                    if (this.numChars <= 0) {
                        return -1;
                    }
                }

                return this.buf[this.curChar++];
            }
        }

        public int nextInt() {
            int c;
            for (c = this.read(); isSpaceChar(c); c = this.read()) {
                ;
            }

            byte sgn = 1;
            if (c == 45) {
                sgn = -1;
                c = this.read();
            }

            int res = 0;

            while (c >= 48 && c <= 57) {
                res *= 10;
                res += c - 48;
                c = this.read();
                if (isSpaceChar(c)) {
                    return res * sgn;
                }
            }

            throw new InputMismatchException();
        }

        public static boolean isSpaceChar(int c) {
            return c == 32 || c == 10 || c == 13 || c == 9 || c == -1;
        }

    }

    static class Utils {
        public static long inv(long N, long M) {
            long x = 0, lastx = 1, y = 1, lasty = 0, q, t, a = N, b = M;
            while (b != 0) {
                q = a / b;
                t = a % b;
                a = b;
                b = t;
                t = x;
                x = lastx - q * x;
                lastx = t;
                t = y;
                y = lasty - q * y;
                lasty = t;
            }
            return (lastx + M) % M;
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void println(long i) {
            writer.println(i);
        }

        public void println(int i) {
            writer.println(i);
        }

    }

    static class Factorials {
        public static long[][] getFIF(int max, int mod) {
            long[] fact = new long[max];
            long[] ifact = new long[max];
            long[] inv = new long[max];
            inv[1] = 1;
            for (int i = 2; i < max; i++) {
                inv[i] = (mod - mod / i) * inv[mod % i] % mod;
            }
            fact[0] = 1;
            ifact[0] = 1;
            for (int i = 1; i < max; i++) {
                fact[i] = fact[i - 1] * i % mod;
                ifact[i] = ifact[i - 1] * inv[i] % mod;
            }
            return new long[][]{fact, ifact, inv};
        }

    }
}

import java.io.*;
import java.util.*;
import java.math.*;
import java.util.concurrent.*;

public final class barels_and_boxes
{
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	static FastScanner sc=new FastScanner(br);
    static PrintWriter out=new PrintWriter(System.out);
	static Random rnd=new Random();
	static long[] fact,inv_fact;
	static int maxn=(int)(2e5+5);
	static long mod=(long)(1e9+7);

	static int add(long a,long b)
	{
		long ret=a+b;

		if(ret>=mod)
		{
			ret%=mod;
		}

		return (int)ret;
	}

	static int mul(long a,long b)
	{
		long ret=a*b;

		if(ret>=mod)
		{
			ret%=mod;
		}

		return (int)ret;
	}

	static long pow(long a,long b)
	{
		long x=1,y=a;

		while(b>0)
		{
			if(b%2==1)
			{
				x=(x*y)%mod;
			}

			y=(y*y)%mod;b=b/2;
		}

		return x;
	}

	static void build()
	{
		fact=new long[maxn];inv_fact=new long[maxn];fact[0]=1;

		for(int i=1;i<maxn;i++)
		{
			fact[i]=(fact[i-1]*i)%mod;
		}

		inv_fact[maxn-1]=pow(fact[maxn-1],mod-2);

		for(int i=maxn-2;i>=0;i--)
		{
			inv_fact[i]=(inv_fact[i+1]*(i+1))%mod;
		}
	}

	static long C(int n,int r)
	{
		if(n-r<0 || Math.min(n,r)<0)
		{
			return 0;
		}

		long val1=fact[n],val2=inv_fact[r],val3=inv_fact[n-r];

		long mul=(val2*val3)%mod;

		return (val1*mul)%mod;
	}

	static long get(long tot,int nums,int flag)
	{
		if(nums==0)
		{
			return (tot==0?1:0);
		}

		else
		{
			if(flag==1)
			{
				return C((int)(tot-1),nums-1);
			}

			else
			{
				return C((int)tot+nums-1,nums-1);
			}
		}
	}

    public static void main(String args[]) throws Exception
    {
		build();

		int f=sc.nextInt(),w=sc.nextInt(),h=sc.nextInt();

		long p=0,q=0;

		for(int i=1;i<=Math.min(f,w);i++)
		{
			long val1=C(f-1,i-1),val2=C(w-1,i-1);

			long zz=mul(val1,val2);

			zz=mul(zz,2);

			q=add(q,zz);

		}

		for(int i=1;i<=f;i++)
		{
			if(w>=i-1)
			{
				long val1=C(f-1,i-1),val2=get(w,i-1,1);

				long zz=mul(val1,val2);

				q=add(q,zz);
			}
		}

		for(int i=1;i<=w;i++)
		{
			if(f>=i-1)
			{
				long val1=C(w-1,i-1),val2=get(f,i-1,1);

				long zz=mul(val1,val2);

				q=add(q,zz);
			}
		}

		for(int i=1;i<=Math.min(f,w);i++)
		{
			long now=(w*1L)-((i*1L*(h+1)));

			if(now>=0)
			{
				long val1=C(f-1,i-1),val2=get(now,i,-1);

				long zz=mul(val1,val2);

				zz=mul(zz,2);

				p=add(p,zz);
			}

		}

		for(int i=1;i<=f;i++)
		{
			if(w>=i-1)
			{
				long now=(w*1L)-((i-1)*1L*(h+1));

				if(now>=0)
				{
					long val1=C(f-1,i-1),val2=get(now,i-1,-1);

					long zz=mul(val1,val2);

					p=add(p,zz);
				}
			}
		}

		for(int i=1;i<=w;i++)
		{
			if(f>=i-1)
			{
				long now=(w*1L)-(i*1L*(h+1));

				if(now>=0)
				{
					long val1=get(now,i,-1),val2=get(f,i-1,1);

					long zz=mul(val1,val2);

					p=add(p,zz);
				}
			}
		}

		long den=pow(q,mod-2),res=mul(p,den);

		out.println(res);out.close();
    }
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Tifuera
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskF solver = new TaskF();
        solver.solve(1, in, out);
        out.close();
    }

    static
    @SuppressWarnings("Duplicates")
    class TaskF {
        private static final long MOD = (long) (1e9 + 7);
        private long[] facts;
        private long[] invFacts;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long f = in.nextInt();
            long w = in.nextInt();
            long h = in.nextInt();

            if (h == 0 || w == 0) {
                out.println(1);
                return;
            }

            initFacts();
            initInverseFacts();

            long lower = getAllVariants(f, w, 0);
            long upper = getAllVariants(f, w, h);

            long lowerInverse = getInverse(lower);

            long result = (upper * lowerInverse) % MOD;

            out.println(result);
        }

        private long getAllVariants(long f, long w, long lowerBound) {
            long result = 0;
            for (long numWineStacks = 1; numWineStacks <= w; numWineStacks++) {
                long winesNum = getSol(numWineStacks, w, lowerBound);

                long foodsFirst = getSol(numWineStacks - 1, f, 0);//n-1 food stacks
                long foodSecond = getSol(numWineStacks, f, 0);// n food stacks
                foodSecond = (2 * foodSecond) % MOD;//can start at two pos

                long foodThird = getSol(numWineStacks + 1, f, 0);//n+1 stack

                long foodNum = (foodsFirst + foodSecond + foodThird) % MOD;
                foodNum = (foodNum + MOD) % MOD;

                long curRes = (winesNum * foodNum) % MOD;

                result = (result + curRes) % MOD;
            }

            return result;
        }

        private long getSol(long num, long sum, long lowerBound) {
            if (num < 1) {
                return 0;
            }
            long upSum = sum - lowerBound * num;
            if (upSum < num) {
                return 0;
            }

            return getCnk(upSum - 1, num - 1);
        }

        private long getCnk(long n, long k) {
            long nFact = getFact(n);
            long kFact = getInvFact(k);
            long nkFact = getInvFact(n - k);

            long result = (kFact * nkFact) % MOD;
            result = (nFact * result) % MOD;

            return result;
        }

        private long getFact(long a) {
            return facts[(int) a];
        }

        private long getInvFact(long a) {
            return invFacts[(int) a];
        }

        private long getInverse(long n) {
            return fastPow(n, MOD - 2);
        }

        private long fastPow(long a, long b) {
            if (b == 0) {
                return 1;
            } else if (b % 2 == 0) {
                long t = fastPow(a, b / 2);
                return (t * t) % MOD;
            } else {
                long t = fastPow(a, b - 1);
                return (t * a) % MOD;
            }
        }

        private void initFacts() {
            facts = new long[(int) (1e5 + 1)];
            facts[0] = 1;
            for (int i = 1; i < facts.length; i++) {
                facts[i] = (i * facts[i - 1]) % MOD;
            }
        }

        private void initInverseFacts() {
            invFacts = new long[(int) (1e5 + 1)];
            for (int i = 0; i < invFacts.length; i++) {
                invFacts[i] = getInverse(facts[i]);
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private String[] currentArray;
        private int curPointer;

        public InputReader(InputStream inputStream) {
            reader = new BufferedReader(new InputStreamReader(inputStream));
        }

        public int nextInt() {
            if ((currentArray == null) || (curPointer >= currentArray.length)) {
                try {
                    currentArray = reader.readLine().split(" ");
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                curPointer = 0;
            }
            return Integer.parseInt(currentArray[curPointer++]);
        }

    }
}

import java.util.Scanner;
public class F399 {

	public static final long p = 1_000_000_007;
	public static long[] factorial;

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int food = in.nextInt();
		int wine = in.nextInt();
		int H = in.nextInt();
		in.close();

		factorial = new long[200001];
		factorial[0] = 1;
		for(int i = 1; i < factorial.length; i++)
			factorial[i] = (factorial[i-1] * i) % p;

		long result = answer(food, wine, H);
		System.out.println(result);
	}

	public static long answer(int food, int wine, int H) {
		if(food == 0) {
			return wine > H? 1 : 0;
		}
		if(wine == 0) {
			return 1;
		}

		long[] foodArr = new long[1 + Math.max(food, wine)];
		long[] wineArr = new long[1 + Math.max(food, wine)];

		for(int i = 1; i < food+1; i++) {
			foodArr[i] = nCr(food - 1, i - 1);
		}

		for(int i = 1; i < wine+1; i++) {
			wineArr[i] = nCr(wine - 1, i - 1);
		}

//		System.out.println("foodArr: " + Arrays.toString(foodArr));
//		System.out.println("wineArr: " + Arrays.toString(wineArr));

		long denom = 0;
		for(int i = 1; i < foodArr.length; i++) {
			denom += 2 * wineArr[i] * foodArr[i];
			denom %= p;
		}

		for(int i = 1; i < foodArr.length-1; i++) {
			denom += foodArr[i] * wineArr[i+1];
			denom += wineArr[i] * foodArr[i+1];
			denom %= p;
		}

//		System.out.println("denom = " + denom);
		long[] validWine = new long[wineArr.length];
		for(int i = 1; i < validWine.length; i++) {
			validWine[i] = nCr(wine + i - 1 - i*(H+1), i-1);
		}

		long numer = 0;
		for(int i = 1; i < foodArr.length; i++) {
			numer += 2 * validWine[i] * foodArr[i];
			denom %= p;
		}

		for(int i = 1; i < foodArr.length-1; i++) {
			numer += foodArr[i] * validWine[i+1];
			numer += validWine[i] * foodArr[i+1];
			numer %= p;
		}

//		System.out.println("numer = " + numer);
//		System.out.println("denom = " + denom);

		long denomInv = modInverse(denom, p);
		long result = numer * denomInv % p;

		return result;
	}

	public static long nCr(int N, int R) {
		if(N == 0 && R == 0) return 1;
		if(N <= 0) return 0;
		if(N < R) return 0;

		long result = factorial[N];
		long denom1 = modInverse(factorial[R], p);
		long denom2 = modInverse(factorial[N-R], p);

		result = (result * denom1) % p;
		result = (result * denom2) % p;

		return result;
	}

	//Extended Euclidean algorithm find x such that ax = 1 (mod m)
	public static long modInverse(long a, long m) {
		long[] a1 = {a, 1, 0};
		long[] b1 = {m, 0, 1};
		while(b1[0] != 0) {
			long[] c1 = new long[3];
			long q = a1[0] / b1[0];
			c1[0] = a1[0] - q * b1[0];
			c1[1] = a1[1] - q * b1[1];
			c1[2] = a1[2] - q * b1[2];
			a1 = b1;
			b1 = c1;
		}

		if(a1[1] < 0) a1[1] += m;
		return a1[1];
	}

}
/*
1 1 1
outputCopy
0
inputCopy
1 2 1
outputCopy
666666672
*/

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 29);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            FBarrelsAndBoxes solver = new FBarrelsAndBoxes();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class FBarrelsAndBoxes {
        Modular mod = new Modular(1e9 + 7);
        int modVal = mod.getMod();
        Combination comb = new Combination(1000000, new Power(mod));

        public void solve(int testNumber, FastInput in, FastOutput out) {
            try {
                solve0(testNumber, in, out);
            } catch (IllegalArgumentException e) {
                out.println(0);
            }
        }

        public void solve0(int testNumber, FastInput in, FastOutput out) {
            int f = in.readInt();
            int w = in.readInt();
            int h = in.readInt();

            int threshold = f + w;

            long total = 0;
            long satisfy = 0;

            //food first
            for (int i = 1; i <= threshold; i++) {
                int forFood = DigitUtils.ceilDiv(i, 2);
                int forWine = i - forFood;
                //alloc
                total += way(forFood, f, 1) * way(forWine, w, 1) % modVal;
                satisfy += way(forFood, f, 1) * way(forWine, w, h + 1) % modVal;
            }

            for (int i = 1; i <= threshold; i++) {
                int forWine = DigitUtils.ceilDiv(i, 2);
                int forFood = i - forWine;

                //alloc
                total += way(forFood, f, 1) * way(forWine, w, 1) % modVal;
                satisfy += way(forFood, f, 1) * way(forWine, w, h + 1) % modVal;
            }

            total %= modVal;
            satisfy %= modVal;

            Power power = new Power(mod);
            long ans = satisfy * power.inverse((int) total) % modVal;
            out.println(ans);
        }

        public long way(int n, int m, int k) {
            if (n == 0) {
                return m == 0 && k == 0 ? 1 : 0;
            }
            if ((long) k * n > m) {
                return 0;
            }
            m -= n * k;
            return comb.combination(m + n - 1, m);
        }

    }

    static class IntExtGCDObject {
        private int[] xy = new int[2];

        public int extgcd(int a, int b) {
            return ExtGCD.extGCD(a, b, xy);
        }

        public int getX() {
            return xy[0];
        }

    }

    static class DigitUtils {
        private DigitUtils() {
        }

        public static int floorDiv(int a, int b) {
            return a < 0 ? -ceilDiv(-a, b) : a / b;
        }

        public static int ceilDiv(int a, int b) {
            if (a < 0) {
                return -floorDiv(-a, b);
            }
            int c = a / b;
            if (c * b < a) {
                return c + 1;
            }
            return c;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class SequenceUtils {
        public static void swap(int[] data, int i, int j) {
            int tmp = data[i];
            data[i] = data[j];
            data[j] = tmp;
        }

    }

    static class Combination implements IntCombination {
        final Factorial factorial;
        int modVal;

        public Combination(Factorial factorial) {
            this.factorial = factorial;
            this.modVal = factorial.getMod().getMod();
        }

        public Combination(int limit, Power pow) {
            this(new Factorial(limit, pow));
        }

        public int combination(int m, int n) {
            if (n > m || n < 0) {
                return 0;
            }
            return (int) ((long) factorial.fact(m) * factorial.invFact(n) % modVal * factorial.invFact(m - n) % modVal);
        }

    }

    static class Power implements InverseNumber {
        static IntExtGCDObject extGCD = new IntExtGCDObject();
        final Modular modular;
        int modVal;

        public Modular getModular() {
            return modular;
        }

        public Power(Modular modular) {
            this.modular = modular;
            this.modVal = modular.getMod();
        }

        public int inverse(int x) {
            int ans = inverseExtGCD(x);
//        if(modular.mul(ans, x) != 1){
//            throw new IllegalStateException();
//        }
            return ans;
        }

        public int inverseExtGCD(int x) {
            if (extGCD.extgcd(x, modVal) != 1) {
                throw new IllegalArgumentException();
            }
            return modular.valueOf(extGCD.getX());
        }

    }

    static class ExtGCD {
        public static int extGCD(int a, int b, int[] xy) {
            if (a >= b) {
                return extGCD0(a, b, xy);
            }
            int ans = extGCD0(b, a, xy);
            SequenceUtils.swap(xy, 0, 1);
            return ans;
        }

        private static int extGCD0(int a, int b, int[] xy) {
            if (b == 0) {
                xy[0] = 1;
                xy[1] = 0;
                return a;
            }
            int ans = extGCD0(b, a % b, xy);
            int x = xy[0];
            int y = xy[1];
            xy[0] = y;
            xy[1] = x - a / b * y;
            return ans;
        }

    }

    static class Factorial {
        int[] fact;
        int[] inv;
        Modular mod;

        public Modular getMod() {
            return mod;
        }

        public Factorial(int[] fact, int[] inv, Power pow) {
            this.mod = pow.getModular();
            this.fact = fact;
            this.inv = inv;
            fact[0] = inv[0] = 1;
            int n = Math.min(fact.length, pow.getModular().getMod());
            for (int i = 1; i < n; i++) {
                fact[i] = i;
                fact[i] = mod.mul(fact[i], fact[i - 1]);
            }
            inv[n - 1] = pow.inverse(fact[n - 1]);
            for (int i = n - 2; i >= 1; i--) {
                inv[i] = mod.mul(inv[i + 1], i + 1);
            }
        }

        public Factorial(int limit, Power pow) {
            this(new int[limit + 1], new int[limit + 1], pow);
        }

        public int fact(int n) {
            return fact[n];
        }

        public int invFact(int n) {
            return inv[n];
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput append(int c) {
            cache.append(c);
            return this;
        }

        public FastOutput append(long c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(int c) {
            return append(c).println();
        }

        public FastOutput println(long c) {
            return append(c).println();
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static interface InverseNumber {
    }

    static class Modular {
        int m;

        public int getMod() {
            return m;
        }

        public Modular(int m) {
            this.m = m;
        }

        public Modular(long m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public Modular(double m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public int valueOf(int x) {
            x %= m;
            if (x < 0) {
                x += m;
            }
            return x;
        }

        public int valueOf(long x) {
            x %= m;
            if (x < 0) {
                x += m;
            }
            return (int) x;
        }

        public int mul(int x, int y) {
            return valueOf((long) x * y);
        }

        public String toString() {
            return "mod " + m;
        }

    }

    static interface IntCombination {
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskF solver = new TaskF();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskF {
        int f;
        int w;
        int h;
        final int mod = (int) (1e9 + 7);
        long[] fact = IntegerUtils.generateFactorial((int) (1e5 + 5), mod);
        long[] revFact = IntegerUtils.generateReverseFactorials((int) (1e5 + 5), mod);

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            f = in.readInt();
            w = in.readInt();
            h = in.readInt();

            if (f == 0 || w == 0) {
                out.printLine(w <= h ? 0 : 1);
                return;
            }

            long p = 0;
            for (int cw = 1; cw <= w && 0 <= w - cw * (h + 1); cw++) {
                int rem = w - cw * (h + 1);
                for (int cf = Math.max(cw - 1, 1); cf <= Math.min(f, cw + 1); cf++) {
                    long cur = f(cw, rem) * f(cf, f - cf) % mod;
                    p += cur;
                    if (cw == cf) {
                        p += cur;
                    }
                    p %= mod;
                }
            }

            long q = 0;
            for (int cw = 1; cw <= w; cw++) {
                for (int cf = Math.max(cw - 1, 1); cf <= Math.min(f, cw + 1); cf++) {
                    long cur = f(cw, w - cw) * f(cf, f - cf) % mod;
                    q += cur;
                    if (cw == cf) {
                        q += cur;
                    }
                    q %= mod;
//                out.printLine(cw, cf, cur, q);
                }
            }
//        out.printLine(p + "/" + q);
            out.printLine(p * IntegerUtils.reverse(q, mod) % mod);
        }

        private long f(int n, int s) {
            return comb(n - 1, s + n - 1);
        }

        private long comb(int m, int n) {
            return fact[n] * revFact[m] % mod * revFact[n - m] % mod;
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void printLine(long i) {
            writer.println(i);
        }

        public void printLine(int i) {
            writer.println(i);
        }

    }

    static class IntegerUtils {
        public static long power(long base, long exponent, long mod) {
            if (base >= mod) {
                base %= mod;
            }
            if (exponent == 0) {
                return 1 % mod;
            }
            long result = power(base, exponent >> 1, mod);
            result = result * result % mod;
            if ((exponent & 1) != 0) {
                result = result * base % mod;
            }
            return result;
        }

        public static long[] generateFactorial(int count, long module) {
            long[] result = new long[count];
            if (module == -1) {
                if (count != 0) {
                    result[0] = 1;
                }
                for (int i = 1; i < count; i++) {
                    result[i] = result[i - 1] * i;
                }
            } else {
                if (count != 0) {
                    result[0] = 1 % module;
                }
                for (int i = 1; i < count; i++) {
                    result[i] = (result[i - 1] * i) % module;
                }
            }
            return result;
        }

        public static long reverse(long number, long module) {
            return power(number, module - 2, module);
        }

        public static long[] generateReverse(int upTo, long module) {
            long[] result = new long[upTo];
            if (upTo > 1) {
                result[1] = 1;
            }
            for (int i = 2; i < upTo; i++) {
                result[i] = (module - module / i * result[((int) (module % i))] % module) % module;
            }
            return result;
        }

        public static long[] generateReverseFactorials(int upTo, long module) {
            long[] result = generateReverse(upTo, module);
            if (upTo > 0) {
                result[0] = 1;
            }
            for (int i = 1; i < upTo; i++) {
                result[i] = result[i] * result[i - 1] % module;
            }
            return result;
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

/**
 * @author Don Li
 */
public class BarrelsBoxes2 {

    int N = (int) 1e6 + 5;
    int MOD = (int) 1e9 + 7;

    long[] inv = new long[N];
    long[] fac = new long[N];
    long[] ifac = new long[N];

    {
        inv[1] = 1;
        for (int i = 2; i < N; i++) inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;

        fac[0] = fac[1] = 1;
        ifac[0] = ifac[1] = 1;
        for (int i = 2; i < N; i++) {
            fac[i] = fac[i - 1] * i % MOD;
            ifac[i] = ifac[i - 1] * inv[i] % MOD;
        }
    }

    void solve() {
        int f = in.nextInt(), w = in.nextInt(), h = in.nextInt();

        long res = 0, tot = bc(f + w, w);
        for (int n = 1; n <= f + 1 && w >= (long) (h + 1) * n; n++) {
            res = (res + bc(f + 1, n) * ways(w - (h + 1) * n, n) % MOD) % MOD;
        }

        long ans = res * inverse(tot) % MOD;
        out.println(ans);
    }

    long ways(int n, int m) {
        if (n == 0 && m == 0) return 1;
        if (n == 0) return 1;
        if (m == 0) return 0;
        return bc(n + m - 1, m - 1);
    }

    long bc(int n, int k) {
        if (n < k) return 0;
        if (n < 0 || k < 0) return 0;
        return fac[n] * ifac[k] % MOD * ifac[n - k] % MOD;
    }

    long inverse(long i) {
        return mpow(i, MOD - 2);
    }

    long mpow(long a, long n) {
        long res = 1;
        while (n > 0) {
            if ((n & 1) > 0) res = res * a % MOD;
            a = a * a % MOD;
            n >>= 1;
        }
        return res;
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new BarrelsBoxes2().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

        public String nextToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(in.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(nextToken());
        }

        public long nextLong() {
            return Long.parseLong(nextToken());
        }

        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

/**
 * @author Don Li
 */
public class BarrelsBoxes {

    int N = (int) 1e6 + 5;
    int MOD = (int) 1e9 + 7;

    long[] inv = new long[N];
    long[] fac = new long[N];
    long[] ifac = new long[N];

    void solve() {
        int f = in.nextInt(), w = in.nextInt(), h = in.nextInt();

        inv[1] = 1;
        for (int i = 2; i < N; i++) inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;

        fac[0] = fac[1] = 1;
        ifac[0] = ifac[1] = 1;
        for (int i = 2; i < N; i++) {
            fac[i] = fac[i - 1] * i % MOD;
            ifac[i] = ifac[i - 1] * inv[i] % MOD;
        }

        int max = Math.min(f + w, 2 * Math.min(f, w) + 1);

        long res = 0, tot = 0;
        for (int n = 1; n <= max; n++) {
            int x = (n + 1) / 2, y = n / 2;
            if (f >= x && w >= y) {
                tot = (tot + bc(w - 1, y - 1) * bc(f - 1, x - 1) % MOD) % MOD;
                if (w >= (long) (h + 1) * y) {
                    int b = w - (h + 1) * y;
                    res = (res + bc(b + y - 1, y - 1) * bc(f - 1, x - 1) % MOD) % MOD;
                }
            }
            if (f >= y && w >= x) {
                tot = (tot + bc(w - 1, x - 1) * bc(f - 1, y - 1) % MOD) % MOD;
                if (w >= (long) (h + 1) * x) {
                    int b = w - (h + 1) * x;
                    res = (res + bc(b + x - 1, x - 1) * bc(f - 1, y - 1) % MOD) % MOD;
                }
            }
        }

        long ans = res * inverse(tot) % MOD;
        out.println(ans);
    }

    long bc(int n, int k) {
        if (n < k) return 0;
        if (n < 0 || k < 0) return 0;
        return fac[n] * ifac[k] % MOD * ifac[n - k] % MOD;
    }

    long inverse(long i) {
        return mpow(i, MOD - 2);
    }

    long mpow(long a, long n) {
        long res = 1;
        while (n > 0) {
            if ((n & 1) > 0) res = res * a % MOD;
            a = a * a % MOD;
            n >>= 1;
        }
        return res;
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new BarrelsBoxes().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

        public String nextToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(in.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(nextToken());
        }

        public long nextLong() {
            return Long.parseLong(nextToken());
        }

        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}

/**
 * @author derrick20
 */

import java.io.*;
import java.util.*;

public class BarrelsBoxes {
    public static void main(String[] args) throws Exception {
        FastScanner sc = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);

        int F = sc.nextInt();
        int W = sc.nextInt();
        int H = sc.nextInt();

        int MAX = (int) 1e5; // todo change this!
        fact = new long[MAX + 1];
        invFact = new long[MAX + 1];
        fact[0] = 1;
        invFact[0] = 1;
        for (int i = 1; i <= MAX; i++) {
            fact[i] = ((long) i * fact[i - 1]) % mod;
            invFact[i] = inv(fact[i]);
        }

        long good = 0;
        for (int k = 1; W - k * (H + 1) >= 0 && F >= k - 1; k++) {
            long amt = (choose(W - k * (H + 1) + k - 1, k - 1) * choose(F + 1, k)) % mod;
            good = (good + amt) % mod;
        }
        long total = 0;
        for (int k = 1; W - k >= 0 && F >= k - 1; k++) {
            long amt = (choose(W - 1, k - 1) * choose(F + 1, k)) % mod;
            total = (total + amt) % mod;
        }
        long prob = (good * inv(total)) % mod;
        out.println(prob);
        out.close();
    }

    // todo SET THE MOD
    static long mod = (long) 1e9 + 7;
    static long[] fact, invFact;

    static long choose(int n, int k) {
        ASSERT(k <= n, "Invalid choose");
        long ans = (fact[n] * invFact[n - k]) % mod;
        return (ans * invFact[k]) % mod;
    }

    static long inv(long x) {
        return fastExpo(x, mod - 2);
    }

    static long fastExpo(long x, long k) {
        long ans = 1;
        long bit = x;
        while (k > 0) {
            if (k % 2 == 1) {
                ans = (bit * ans) % mod;
            }
            bit = (bit * bit) % mod;
            k /= 2;
        }
        return ans;
    }

    static class FastScanner {
        private int BS = 1 << 16;
        private char NC = (char) 0;
        private byte[] buf = new byte[BS];
        private int bId = 0, size = 0;
        private char c = NC;
        private double cnt = 1;
        private BufferedInputStream in;

        public FastScanner() {
            in = new BufferedInputStream(System.in, BS);
        }

        public FastScanner(String s) {
            try {
                in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
            } catch (Exception e) {
                in = new BufferedInputStream(System.in, BS);
            }
        }

        private char getChar() {
            while (bId == size) {
                try {
                    size = in.read(buf);
                } catch (Exception e) {
                    return NC;
                }
                if (size == -1) return NC;
                bId = 0;
            }
            return (char) buf[bId++];
        }

        public int nextInt() {
            return (int) nextLong();
        }

        public int[] nextInts(int N) {
            int[] res = new int[N];
            for (int i = 0; i < N; i++) {
                res[i] = (int) nextLong();
            }
            return res;
        }

        public long[] nextLongs(int N) {
            long[] res = new long[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextLong();
            }
            return res;
        }

        public long nextLong() {
            cnt = 1;
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            long res = 0;
            for (; c >= '0' && c <= '9'; c = getChar()) {
                res = (res << 3) + (res << 1) + c - '0';
                cnt *= 10;
            }
            return neg ? -res : res;
        }

        public double nextDouble() {
            double cur = nextLong();
            return c != '.' ? cur : cur + nextLong() / cnt;
        }

        public double[] nextDoubles(int N) {
            double[] res = new double[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextDouble();
            }
            return res;
        }

        public String next() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c > 32) {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public String nextLine() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c != '\n') {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public boolean hasNext() {
            if (c > 32) return true;
            while (true) {
                c = getChar();
                if (c == NC) return false;
                else if (c > 32) return true;
            }
        }
    }

    static void ASSERT(boolean assertion, String message) {
        if (!assertion) throw new AssertionError(message);
    }
}

/**
 * @author derrick20
 */

import java.io.*;
import java.util.*;

public class BarrelsBoxes {
    public static void main(String[] args) throws Exception {
        FastScanner sc = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);

        int F = sc.nextInt();
        int W = sc.nextInt();
        int H = sc.nextInt();

        int MAX = (int) 1e5 + 1; // todo change this!
        fact = new long[MAX + 1];
        invFact = new long[MAX + 1];
        fact[0] = 1;
        invFact[0] = 1;
        for (int i = 1; i <= MAX; i++) {
            fact[i] = ((long) i * fact[i - 1]) % mod;
            invFact[i] = inv(fact[i]);
        }

        long good = 0;
        for (int k = 1; W - k * (H + 1) >= 0 && F >= k - 1; k++) {
            long amt = (choose(W - k * (H + 1) + k - 1, k - 1) * choose(F + 1, k)) % mod;
            good = (good + amt) % mod;
        }
        long total = 0;
        for (int k = 1; W - k >= 0 && F >= k - 1; k++) {
            long amt = (choose(W - 1, k - 1) * choose(F + 1, k)) % mod;
            total = (total + amt) % mod;
        }
        long prob = (good * inv(total)) % mod;
        out.println(prob);
        out.close();
    }

    // todo SET THE MOD
    static long mod = (long) 1e9 + 7;
    static long[] fact, invFact;

    static long choose(int n, int k) {
        ASSERT(k <= n, "Invalid choose");
        long ans = (fact[n] * invFact[n - k]) % mod;
        return (ans * invFact[k]) % mod;
    }

    static long inv(long x) {
        return fastExpo(x, mod - 2);
    }

    static long fastExpo(long x, long k) {
        long ans = 1;
        long bit = x;
        while (k > 0) {
            if (k % 2 == 1) {
                ans = (bit * ans) % mod;
            }
            bit = (bit * bit) % mod;
            k /= 2;
        }
        return ans;
    }

    static class FastScanner {
        private int BS = 1 << 16;
        private char NC = (char) 0;
        private byte[] buf = new byte[BS];
        private int bId = 0, size = 0;
        private char c = NC;
        private double cnt = 1;
        private BufferedInputStream in;

        public FastScanner() {
            in = new BufferedInputStream(System.in, BS);
        }

        public FastScanner(String s) {
            try {
                in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
            } catch (Exception e) {
                in = new BufferedInputStream(System.in, BS);
            }
        }

        private char getChar() {
            while (bId == size) {
                try {
                    size = in.read(buf);
                } catch (Exception e) {
                    return NC;
                }
                if (size == -1) return NC;
                bId = 0;
            }
            return (char) buf[bId++];
        }

        public int nextInt() {
            return (int) nextLong();
        }

        public int[] nextInts(int N) {
            int[] res = new int[N];
            for (int i = 0; i < N; i++) {
                res[i] = (int) nextLong();
            }
            return res;
        }

        public long[] nextLongs(int N) {
            long[] res = new long[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextLong();
            }
            return res;
        }

        public long nextLong() {
            cnt = 1;
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            long res = 0;
            for (; c >= '0' && c <= '9'; c = getChar()) {
                res = (res << 3) + (res << 1) + c - '0';
                cnt *= 10;
            }
            return neg ? -res : res;
        }

        public double nextDouble() {
            double cur = nextLong();
            return c != '.' ? cur : cur + nextLong() / cnt;
        }

        public double[] nextDoubles(int N) {
            double[] res = new double[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextDouble();
            }
            return res;
        }

        public String next() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c > 32) {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public String nextLine() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c != '\n') {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public boolean hasNext() {
            if (c > 32) return true;
            while (true) {
                c = getChar();
                if (c == NC) return false;
                else if (c > 32) return true;
            }
        }
    }

    static void ASSERT(boolean assertion, String message) {
        if (!assertion) throw new AssertionError(message);
    }
}

/**
 * @author derrick20
 */

import java.io.*;
import java.util.*;

public class BarrelsBoxes {
    public static void main(String[] args) throws Exception {
        FastScanner sc = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);

        int F = sc.nextInt();
        int W = sc.nextInt();
        int H = sc.nextInt();

        int MAX = (int) 1e5; // todo change this!
        fact = new long[MAX + 1];
        invFact = new long[MAX + 1];
        fact[0] = 1;
        invFact[0] = 1;
        for (int i = 1; i <= MAX; i++) {
            fact[i] = ((long) i * fact[i - 1]) % mod;
            invFact[i] = inv(fact[i]);
        }

        long good = 0;
        for (int k = 1; W - k * (H + 1) >= 0 && F >= k - 1; k++) {
            long amt = (choose(W - k * (H + 1), k - 1) * choose(F + 1, k)) % mod;
            good = (good + amt) % mod;
        }
        long total = 0;
        for (int k = 1; W - k >= 0 && F >= k - 1; k++) {
            long amt = (choose(W - 1, k - 1) * choose(F + 1, k)) % mod;
            total = (total + amt) % mod;
        }
        long prob = (good * inv(total)) % mod;
        out.println(prob);
        out.close();
    }

    // todo SET THE MOD
    static long mod = (long) 1e9 + 7;
    static long[] fact, invFact;

    static long choose(int n, int k) {
        ASSERT(k <= n, "Invalid choose");
        long ans = (fact[n] * invFact[n - k]) % mod;
        return (ans * invFact[k]) % mod;
    }

    static long inv(long x) {
        return fastExpo(x, mod - 2);
    }

    static long fastExpo(long x, long k) {
        long ans = 1;
        long bit = x;
        while (k > 0) {
            if (k % 2 == 1) {
                ans = (bit * ans) % mod;
            }
            bit = (bit * bit) % mod;
            k /= 2;
        }
        return ans;
    }

    static class FastScanner {
        private int BS = 1 << 16;
        private char NC = (char) 0;
        private byte[] buf = new byte[BS];
        private int bId = 0, size = 0;
        private char c = NC;
        private double cnt = 1;
        private BufferedInputStream in;

        public FastScanner() {
            in = new BufferedInputStream(System.in, BS);
        }

        public FastScanner(String s) {
            try {
                in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
            } catch (Exception e) {
                in = new BufferedInputStream(System.in, BS);
            }
        }

        private char getChar() {
            while (bId == size) {
                try {
                    size = in.read(buf);
                } catch (Exception e) {
                    return NC;
                }
                if (size == -1) return NC;
                bId = 0;
            }
            return (char) buf[bId++];
        }

        public int nextInt() {
            return (int) nextLong();
        }

        public int[] nextInts(int N) {
            int[] res = new int[N];
            for (int i = 0; i < N; i++) {
                res[i] = (int) nextLong();
            }
            return res;
        }

        public long[] nextLongs(int N) {
            long[] res = new long[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextLong();
            }
            return res;
        }

        public long nextLong() {
            cnt = 1;
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            long res = 0;
            for (; c >= '0' && c <= '9'; c = getChar()) {
                res = (res << 3) + (res << 1) + c - '0';
                cnt *= 10;
            }
            return neg ? -res : res;
        }

        public double nextDouble() {
            double cur = nextLong();
            return c != '.' ? cur : cur + nextLong() / cnt;
        }

        public double[] nextDoubles(int N) {
            double[] res = new double[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextDouble();
            }
            return res;
        }

        public String next() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c > 32) {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public String nextLine() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c != '\n') {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public boolean hasNext() {
            if (c > 32) return true;
            while (true) {
                c = getChar();
                if (c == NC) return false;
                else if (c > 32) return true;
            }
        }
    }

    static void ASSERT(boolean assertion, String message) {
        if (!assertion) throw new AssertionError(message);
    }
}

// practice with rainboy
import java.io.*;
import java.util.*;

public class CF768F extends PrintWriter {
	CF768F() { super(System.out, true); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF768F o = new CF768F(); o.main(); o.flush();
	}

	static final int MD = 1000000007;
	int d_, x_, y_;
	void gcd_(int a, int b) {
		if (b == 0) {
			d_ = a;
			x_ = 1; y_ = 0;
		} else {
			gcd_(b, a % b);
			int tmp = x_ - a / b * y_; x_ = y_; y_ = tmp;
		}
	}
	int inv(int a, int b) {
		gcd_(a, b);
		return x_;
	}
	int[] ff, gg;
	void init(int n) {
		ff = new int[n];
		gg = new int[n];
		for (int i = 0, f = 1; i < n; i++) {
			gg[i] = inv(ff[i] = f, MD);
			f = (int) ((long) f * (i + 1) % MD);
		}
	}
	int choose(int n, int k) {
		return n < k ? 0 : (int) ((long) ff[n] * gg[k] % MD * gg[n - k] % MD);
	}
	void main() {
		int f = sc.nextInt();
		int w = sc.nextInt();
		int h = sc.nextInt();
		if (f == 0) {
			println(w > h ? 1 : 0);
			return;
		}
		if (w == 0) {
			println(1);
			return;
		}
		int n = Math.max(f, w);
		init(n);
		int[] aa = new int[n + 2];
		for (int i = 1; i <= f; i++)
			aa[i] = choose(f - 1, i - 1);
		int[] bb = new int[n + 2];
		for (int j = 1; j <= w; j++)
			bb[j] = choose(w - 1, j - 1);
		int[] cc = new int[n + 2];
		for (int j = 1; h * j < w; j++)
			cc[j] = choose(w - h * j - 1, j - 1);
		int p = 0, q = 0;
		for (int i = 1; i <= n; i++) {
			p = (int) ((p + aa[i] * (cc[i] * 2L + cc[i - 1] + cc[i + 1])) % MD);
			q = (int) ((q + aa[i] * (bb[i] * 2L + bb[i - 1] + bb[i + 1])) % MD);
		}
		int ans = (int) ((long) p * inv(q, MD) % MD);
		if (ans < 0)
			ans += MD;
		println(ans);
	}
}

import java.util.*;
import java.io.*;

public class BarrelBox {
    static long f[] = new long [400010];
    final static int mod = 1000000000 + 7;
    static long bigmod(long a, long b) {
        if(b == 0) return 1;
        if((b & 1) == 1) return (bigmod(a, b - 1) * a) % mod;
        long m = bigmod(a, b >> 1);
        return (m * m) % mod;
    }
    static long inverse(long a) {
        return bigmod(a, mod - 2);
    }
    static long nCr(int n, int r) {
        if(n < 0 || r < 0) return 0;
        if(n < r) return 0;
        long num = f[n];
        long den = (f[r] * f[n - r]) % mod;
        return (num * inverse(den)) % mod;
    }
    static long junk(int n, int k) {
        return nCr(n - 1, k - 1);
    }
    public static void main(String [] args) {
        Reader in = new Reader ();
        f[0] = 1;
        for(int i = 1; i <= 400000; i++) {
            f[i] = f[i - 1] * i;
            f[i] %= mod;
        }

        int f = in.nextInt();
        int w = in.nextInt();
        int h = in.nextInt();

        if(f == 0) {
            if(w > h) System.out.println(1);
            else System.out.println(0);
            System.exit(0);
        }
        if(w == 0) {
            System.out.println(0);
            System.exit(0);
        }

        long p = 0;
        for(int i = 1; i <= w; i++) {
            int x = w - (i * h);
            if(x < 0) break;
            long ways = junk(x, i);
            p += ways * junk(f, i + 1);
            p %= mod;
            p += ways * junk(f, i) * 2;
            p %= mod;
            p += ways * junk(f, i - 1);
            p %= mod;
        }

        long q = 0;
        for(int i = 1; i <= w; i++) {
            long ways = junk(w, i);
            q += ways * junk(f, i + 1);
            q %= mod;
            q += ways * junk(f, i) * 2;
            q %= mod;
            q += ways * junk(f, i - 1);
            q %= mod;
        }
        long ans = p * inverse(q);
        System.out.println(ans % mod);
    }
    static class Reader {
        private StringTokenizer a;
        private BufferedReader b;
        Reader () {
            a = null;
            b = new BufferedReader (new InputStreamReader (System.in));
        }
        public String next () {
            while(a == null || !a.hasMoreTokens()) {
                try {
                    a = new StringTokenizer (b.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return a.nextToken();
        }
        public int nextInt() {
            return Integer.parseInt(this.next());
        }
        public long nextLong () {
            return Long.parseLong(this.next());
        }
        public double nextDouble () {
            return Double.parseDouble(this.next());
        }
        public String nextLine() {
            try {
                return b.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }
    }
    static class Writer {
        private PrintWriter a;
        private StringBuffer b;
        Writer () {
            a = new PrintWriter (System.out);
            b = new StringBuffer ("");
        }
        public void write (Object s) {
            b.append(s);
        }
        public void writeln(Object s) {
            b.append(s).append('\n');
        }
        public void flush () {
            a.print(b);
            a.flush();
            a.close();
        }
    }
}

import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

public class Template implements Runnable {

    BufferedReader in;
    PrintWriter out;
    StringTokenizer tok = new StringTokenizer("");

    void init() throws FileNotFoundException {
        try {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        } catch (Exception e) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        }
    }

    String readString() throws IOException {
        while (!tok.hasMoreTokens()) {
            try {
                tok = new StringTokenizer(in.readLine());
            } catch (Exception e) {
                return null;
            }
        }
        return tok.nextToken();
    }

    int readInt() throws IOException {
        return Integer.parseInt(readString());
    }

    int[] readIntArray(int size) throws IOException {
        int[] res = new int[size];
        for (int i = 0; i < size; i++) {
            res[i] = readInt();
        }
        return res;
    }

    long readLong() throws IOException {
        return Long.parseLong(readString());
    }

    double readDouble() throws IOException {
        return Double.parseDouble(readString());
    }

    <T> List<T>[] createGraphList(int size) {
        List<T>[] list = new List[size];
        for (int i = 0; i < size; i++) {
            list[i] = new ArrayList<>();
        }
        return list;
    }

    public static void main(String[] args) {
        new Template().run();
        // new Thread(null, new Template(), "", 1l * 200 * 1024 * 1024).start();
    }

    long timeBegin, timeEnd;

    void time() {
        timeEnd = System.currentTimeMillis();
        System.err.println("Time = " + (timeEnd - timeBegin));
    }

    long memoryTotal, memoryFree;

    void memory() {
        memoryFree = Runtime.getRuntime().freeMemory();
        System.err.println("Memory = " + ((memoryTotal - memoryFree) >> 10)
                + " KB");
    }

    public void run() {
        try {
            timeBegin = System.currentTimeMillis();
            memoryTotal = Runtime.getRuntime().freeMemory();
            init();
            solve();
            out.close();
            if (System.getProperty("ONLINE_JUDGE") == null) {
                time();
                memory();
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }

    long[] fact;
    long[] revfact;
    int mod = (int) 1e9 + 7;

    long binpow(long x, int p, int mod) {
        if (p == 0) {
            return 1 % mod;
        }
        if (p % 2 == 0) {
            long half = binpow(x, p / 2, mod);
            return half * half % mod;
        } else {
            return x * binpow(x, p - 1, mod) % mod;
        }
    }

    long C(int n, int k) {
        long answer = fact[n];
        answer = answer * revfact[n - k] % mod;
        answer = answer * revfact[k] % mod;
        return answer;
    }

    long ways(int columns, int count, int minHeight) {
        if (columns == 0) {
            if (count == 0) return 1;
            return 0;
        }
        if (count / minHeight < columns) return 0;
        int ost = count - columns * minHeight;
        return binpow(columns, ost, mod);
    }

    void solve() throws IOException {
//        int MAX = (int) 1e5 + 5;
//        fact = new long[MAX];
//        revfact = new long[MAX];
//        fact[0] = 1;
//        for (int i = 1; i < MAX; i++) {
//            fact[i] = fact[i - 1] * i % mod;
//            revfact[i] = binpow(fact[i], mod - 2, mod);
//        }
        int f = readInt();
        int w = readInt();
        int h = readInt();
        if (w == 0) {
            out.println(1);
            return;
        }

        long correct = 0;
        long all = 0;

        for (int wineColumns = 1; wineColumns <= w; wineColumns++) {
            long foodCount = (ways(wineColumns - 1, f, 1) + ways(wineColumns + 1, f, 1) + ways(wineColumns, f, 1) * 2) % mod;
            all += ways(wineColumns, w, 1) * foodCount % mod;
            all %= mod;
            correct += ways(wineColumns, w, h + 1) * foodCount % mod;
            correct %= mod;
        }
        out.println(correct * binpow(all, mod - 2, mod) % mod);
    }

}

// package codeforces.cf3xx.cf399;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class F {
    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);

        int f = in.nextInt();
        int w = in.nextInt();
        int h = in.nextInt();

        prec(300000);

        long ptn = 0;
        for (int pile = 1 ; pile <= f+1 ; pile++) {
            int leftW = w - (h + 1) * pile;
            if (leftW < 0) {
                break;
            }
            ptn += comb(f+1, pile) * comb(leftW+pile-1, pile-1) % MOD;
        }
        long all = comb(f+w, f) % MOD;
        if (w == 0) {
            ptn = 1;
        }
        out.println(ptn * inv(all) % MOD);
        out.flush();
    }

    static final int MOD = 1000000007;

    static long pow(long a, long x) {
        long res = 1;
        while (x > 0) {
            if (x%2 != 0) {
                res = (res*a)%MOD;
            }
            a = (a*a)%MOD;
            x /= 2;
        }
        return res;
    }

    static long inv(long a) {
        return pow(a, MOD-2)%MOD;
    }

    static long[] _fact;
    static long[] _invfact;

    static long comb(long ln, long lr) {
        int n = (int) ln;
        int r = (int) lr;
        if (n < 0 || r < 0 || r > n) {
            return 0;
        }
        if (r > n/2) {
            r = n-r;
        }
        return (((_fact[n]*_invfact[n-r])%MOD)*_invfact[r])%MOD;
    }

    static void prec(int n) {
        _fact = new long[n+1];
        _invfact = new long[n+1];
        _fact[0] = 1;
        _invfact[0] = 1;
        for (int i = 1; i <= n; i++) {
            _fact[i] = _fact[i-1]*i%MOD;
            _invfact[i] = inv(_fact[i]);
        }
    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        private int[] nextInts(int n) {
            int[] ret = new int[n];
            for (int i = 0; i < n; i++) {
                ret[i] = nextInt();
            }
            return ret;
        }

        private int[][] nextIntTable(int n, int m) {
            int[][] ret = new int[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    ret[i][j] = nextInt();
                }
            }
            return ret;
        }

        private long[] nextLongs(int n) {
            long[] ret = new long[n];
            for (int i = 0; i < n; i++) {
                ret[i] = nextLong();
            }
            return ret;
        }

        private long[][] nextLongTable(int n, int m) {
            long[][] ret = new long[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    ret[i][j] = nextLong();
                }
            }
            return ret;
        }

        private double[] nextDoubles(int n) {
            double[] ret = new double[n];
            for (int i = 0; i < n; i++) {
                ret[i] = nextDouble();
            }
            return ret;
        }

        private int next() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public char nextChar() {
            int c = next();
            while (isSpaceChar(c))
                c = next();
            if ('a' <= c && c <= 'z') {
                return (char) c;
            }
            if ('A' <= c && c <= 'Z') {
                return (char) c;
            }
            throw new InputMismatchException();
        }

        public String nextToken() {
            int c = next();
            while (isSpaceChar(c))
                c = next();
            StringBuilder res = new StringBuilder();
            do {
                res.append((char) c);
                c = next();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public int nextInt() {
            int c = next();
            while (isSpaceChar(c))
                c = next();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = next();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c-'0';
                c = next();
            } while (!isSpaceChar(c));
            return res*sgn;
        }

        public long nextLong() {
            int c = next();
            while (isSpaceChar(c))
                c = next();
            long sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = next();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c-'0';
                c = next();
            } while (!isSpaceChar(c));
            return res*sgn;
        }

        public double nextDouble() {
            return Double.valueOf(nextToken());
        }

        public boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    static void debug(Object... o) {
        System.err.println(Arrays.deepToString(o));
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskF solver = new TaskF();
		solver.solve(1, in, out);
		out.close();
	}

	static class TaskF {
		int n;
		int m;
		int h;
		int good = 0;
		int total = 0;
		final int N = 200010;
		final int MOD = (int) (1e9 + 7);
		int[] fact = new int[N];
		int[] inv = new int[N];
		int[] invFact = new int[N];

		public void solve(int testNumber, FastScanner in, PrintWriter out) {
			precalc();
			n = in.nextInt();
			m = in.nextInt();
			h = in.nextInt();
			for (int total = 1; total <= n + m; total++) {
				int a = total / 2;
				int b = total - a;
				check(a, b);
				check(b, a);
			}
			out.println(good * (long) inv(total) % MOD);

		}

		private void check(int a, int b) {
			total = (int) ((total + (long) f(n - a, a) * f(m - b, b)) % MOD);
			if ((long) m - b * (long) (h + 1) < 0) {
				return;
			}
			good = (int) ((good + (long) f(n - a, a) * f(m - b * (h + 1), b)) % MOD);
		}

		private int f(int n, int k) {
			if (n < 0 || k < 0) {
				return 0;
			}
			return C(n + k - 1, k - 1);
		}

		private void precalc() {
			inv[1] = 1;
			for (int i = 2; i < N; i++) {
				inv[i] = (int) ((MOD - (MOD / i) * (long) inv[MOD % i] % MOD) % MOD);
			}
			fact[0] = 1;
			invFact[0] = 1;
			for (int i = 1; i < N; i++) {
				fact[i] = (int) (i * (long) fact[i - 1] % MOD);
				invFact[i] = (int) (inv[i] * (long) invFact[i - 1] % MOD);
			}
		}

		private int C(int n, int k) {
			if (k < 0 || k > n) return 0;
			long a = fact[n];
			long b = invFact[k];
			b = b * invFact[n - k] % MOD;
			return (int) (a * b % MOD);
		}

		private int inv(int x) {
			return pow(x, MOD - 2);
		}

		private int pow(long a, long n) {
			long r = 1;
			while (n > 0) {
				if (n % 2 == 1) {
					r = r * a % MOD;
				}
				a = a * a % MOD;
				n /= 2;
			}
			return (int) r;
		}

	}

	static class FastScanner {
		private BufferedReader in;
		private StringTokenizer st;

		public FastScanner(InputStream stream) {
			in = new BufferedReader(new InputStreamReader(stream));
		}

		public String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					String rl = in.readLine();
					if (rl == null) {
						return null;
					}
					st = new StringTokenizer(rl);
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

	}
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskF solver = new TaskF();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskF {
        public int mod = 1000000007;
        public long[] fact;
        public long[] ifact;

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int f = in.nextInt(), w = in.nextInt(), h = in.nextInt();
            if (w == 0) {
                out.println(0);
                return;
            }
            if (f == 0) {
                if (w > h) out.println(1);
                else out.println(0);
                return;
            }
            long[][] x = Factorials.getFIF(f + w + 1, mod);
            fact = x[0];
            ifact = x[1];
            // starts with f
            long num = 0, den = 0;
            for (int len = 1; len <= w + f; len++) {
                int needf = (len + 1) / 2;
                if (needf > f) break;
                int needw = len / 2;
                if (needw > w) break;
                long a1 = nways(f - needf, needf);
                den = (den + a1 * nways(w - needw, needw)) % mod;
                if (1L * needw * (h + 1) <= w)
                    num = (num + a1 * nways(w - needw * (h + 1), needw)) % mod;
            }
            // starts with w
            for (int len = 1; len <= w + f; len++) {
                int needw = (len + 1) / 2;
                if (needw > w) break;
                int needf = len / 2;
                if (needf > f) break;
                long a1 = nways(f - needf, needf);
                den = (den + a1 * nways(w - needw, needw)) % mod;
                if (1L * needw * (h + 1) <= w)
                    num = (num + a1 * nways(w - needw * (h + 1), needw)) % mod;
            }

            out.println(num * Utils.inv(den, mod) % mod);
        }

        public long nways(int i, int j) {
            if (i < 0) return 0;
            if (j == 0) {
                return i == 0 ? 1 : 0;
            }
            return fact[i + j - 1] * ifact[j - 1] % mod * ifact[i] % mod;
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (this.numChars == -1) {
                throw new InputMismatchException();
            } else {
                if (this.curChar >= this.numChars) {
                    this.curChar = 0;

                    try {
                        this.numChars = this.stream.read(this.buf);
                    } catch (IOException var2) {
                        throw new InputMismatchException();
                    }

                    if (this.numChars <= 0) {
                        return -1;
                    }
                }

                return this.buf[this.curChar++];
            }
        }

        public int nextInt() {
            int c;
            for (c = this.read(); isSpaceChar(c); c = this.read()) {
                ;
            }

            byte sgn = 1;
            if (c == 45) {
                sgn = -1;
                c = this.read();
            }

            int res = 0;

            while (c >= 48 && c <= 57) {
                res *= 10;
                res += c - 48;
                c = this.read();
                if (isSpaceChar(c)) {
                    return res * sgn;
                }
            }

            throw new InputMismatchException();
        }

        public static boolean isSpaceChar(int c) {
            return c == 32 || c == 10 || c == 13 || c == 9 || c == -1;
        }

    }

    static class Utils {
        public static long inv(long N, long M) {
            long x = 0, lastx = 1, y = 1, lasty = 0, q, t, a = N, b = M;
            while (b != 0) {
                q = a / b;
                t = a % b;
                a = b;
                b = t;
                t = x;
                x = lastx - q * x;
                lastx = t;
                t = y;
                y = lasty - q * y;
                lasty = t;
            }
            return (lastx + M) % M;
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void println(long i) {
            writer.println(i);
        }

        public void println(int i) {
            writer.println(i);
        }

    }

    static class Factorials {
        public static long[][] getFIF(int max, int mod) {
            long[] fact = new long[max];
            long[] ifact = new long[max];
            long[] inv = new long[max];
            inv[1] = 1;
            for (int i = 2; i < max; i++) {
                inv[i] = (mod - mod / i) * inv[mod % i] % mod;
            }
            fact[0] = 1;
            ifact[0] = 1;
            for (int i = 1; i < max; i++) {
                fact[i] = fact[i - 1] * i % mod;
                ifact[i] = ifact[i - 1] * inv[i] % mod;
            }
            return new long[][]{fact, ifact, inv};
        }

    }
}

import java.io.*;
import java.util.*;
import java.math.*;
import java.util.concurrent.*;

public final class barels_and_boxes
{
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	static FastScanner sc=new FastScanner(br);
    static PrintWriter out=new PrintWriter(System.out);
	static Random rnd=new Random();
	static long[] fact,inv_fact;
	static int maxn=(int)(2e5+5);
	static long mod=(long)(1e9+7);

	static int add(long a,long b)
	{
		long ret=a+b;

		if(ret>=mod)
		{
			ret%=mod;
		}

		return (int)ret;
	}

	static int mul(long a,long b)
	{
		long ret=a*b;

		if(ret>=mod)
		{
			ret%=mod;
		}

		return (int)ret;
	}

	static long pow(long a,long b)
	{
		long x=1,y=a;

		while(b>0)
		{
			if(b%2==1)
			{
				x=(x*y)%mod;
			}

			y=(y*y)%mod;b=b/2;
		}

		return x;
	}

	static void build()
	{
		fact=new long[maxn];inv_fact=new long[maxn];fact[0]=1;

		for(int i=1;i<maxn;i++)
		{
			fact[i]=(fact[i-1]*i)%mod;
		}

		inv_fact[maxn-1]=pow(fact[maxn-1],mod-2);

		for(int i=maxn-2;i>=0;i--)
		{
			inv_fact[i]=(inv_fact[i+1]*(i+1))%mod;
		}
	}

	static long C(int n,int r)
	{
		if(n-r<0 || Math.min(n,r)<0)
		{
			return 0;
		}

		long val1=fact[n],val2=inv_fact[r],val3=inv_fact[n-r];

		long mul=(val2*val3)%mod;

		return (val1*mul)%mod;
	}

	static long get(long tot,int nums,int flag)
	{
		if(nums==0)
		{
			return (tot==0?1:0);
		}

		else
		{
			if(flag==1)
			{
				return C((int)(tot-1),nums-1);
			}

			else
			{
				return C((int)tot+nums-1,nums-1);
			}
		}
	}

    public static void main(String args[]) throws Exception
    {
		build();

		int f=sc.nextInt(),w=sc.nextInt(),h=sc.nextInt();

		long p=0,q=0;

		for(int i=1;i<=Math.min(f,w);i++)
		{
			long val1=C(f-1,i-1),val2=C(w-1,i-1);

			long zz=mul(val1,val2);

			zz=mul(zz,2);

			q=add(q,zz);

		}

		for(int i=1;i<=f;i++)
		{
			if(w>=i-1)
			{
				long val1=C(f-1,i-1),val2=get(w,i-1,1);

				long zz=mul(val1,val2);

				q=add(q,zz);
			}
		}

		for(int i=1;i<=w;i++)
		{
			if(f>=i-1)
			{
				long val1=C(w-1,i-1),val2=get(f,i-1,1);

				long zz=mul(val1,val2);

				q=add(q,zz);
			}
		}

		for(int i=1;i<=Math.min(f,w);i++)
		{
			long now=(w*1L)-((i*1L*(h+1)));

			if(now>=0)
			{
				long val1=C(f-1,i-1),val2=get(now,i,h==0?1:-1);

				long zz=mul(val1,val2);

				zz=mul(zz,2);

				p=add(p,zz);
			}

		}

		for(int i=1;i<=f;i++)
		{
			if(w>=i-1)
			{
				long now=(w*1L)-((i-1)*1L*(h+1));

				if(now>=0)
				{
					long val1=C(f-1,i-1),val2=get(now,i-1,h==0?1:-1);

					long zz=mul(val1,val2);

					p=add(p,zz);
				}
			}
		}

		for(int i=1;i<=w;i++)
		{
			if(f>=i-1)
			{
				long now=(w*1L)-(i*1L*(h+1));

				if(now>=0)
				{
					long val1=get(now,i,h==0?1:-1),val2=get(f,i-1,1);

					long zz=mul(val1,val2);

					p=add(p,zz);
				}
			}
		}

		long den=pow(q,mod-2),res=mul(p,den);

		out.println(res);out.close();
    }
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}

import java.io.*;
import java.util.*;
import java.math.*;
import java.util.concurrent.*;

public final class barels_and_boxes
{
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	static FastScanner sc=new FastScanner(br);
    static PrintWriter out=new PrintWriter(System.out);
	static Random rnd=new Random();
	static long[] fact,inv_fact;
	static int maxn=(int)(2e5+5);
	static long mod=(long)(1e9+7);

	static int add(long a,long b)
	{
		long ret=a+b;

		if(ret>=mod)
		{
			ret%=mod;
		}

		return (int)ret;
	}

	static int mul(long a,long b)
	{
		long ret=a*b;

		if(ret>=mod)
		{
			ret%=mod;
		}

		return (int)ret;
	}

	static long pow(long a,long b)
	{
		long x=1,y=a;

		while(b>0)
		{
			if(b%2==1)
			{
				x=(x*y)%mod;
			}

			y=(y*y)%mod;b=b/2;
		}

		return x;
	}

	static void build()
	{
		fact=new long[maxn];inv_fact=new long[maxn];fact[0]=1;

		for(int i=1;i<maxn;i++)
		{
			fact[i]=(fact[i-1]*i)%mod;
		}

		inv_fact[maxn-1]=pow(fact[maxn-1],mod-2);

		for(int i=maxn-2;i>=0;i--)
		{
			inv_fact[i]=(inv_fact[i+1]*(i+1))%mod;
		}
	}

	static long C(int n,int r)
	{
		if(n-r<0 || Math.min(n,r)<0)
		{
			return 0;
		}

		long val1=fact[n],val2=inv_fact[r],val3=inv_fact[n-r];

		long mul=(val2*val3)%mod;

		return (val1*mul)%mod;
	}

	static long get(long tot,int nums,int flag)
	{
		if(nums==0)
		{
			return (tot==0?1:0);
		}

		else
		{
			if(flag==1)
			{
				return C((int)(tot-1),nums-1);
			}

			else
			{
				return C((int)tot+nums-1,nums-1);
			}
		}
	}

    public static void main(String args[]) throws Exception
    {
		build();

		int f=sc.nextInt(),w=sc.nextInt(),h=sc.nextInt();

		long p=0,q=0;

		for(int i=1;i<=Math.min(f,w);i++)
		{
			long val1=C(f-1,i-1),val2=C(w-1,i-1);

			long zz=mul(val1,val2);

			zz=mul(zz,2);

			q=add(q,zz);

		}

		for(int i=1;i<=f;i++)
		{
			if(w>=i-1)
			{
				long val1=C(f-1,i-1),val2=get(w,i-1,1);

				long zz=mul(val1,val2);

				q=add(q,zz);
			}
		}

		for(int i=1;i<=w;i++)
		{
			if(f>=i-1)
			{
				long val1=C(w-1,i-1),val2=get(f,i-1,1);

				long zz=mul(val1,val2);

				q=add(q,zz);
			}
		}

		for(int i=1;i<=Math.min(f,w);i++)
		{
			long now=(1L*w)-((i*1L*(h+1)));

			if(now>=0)
			{
				long val1=C(f-1,i-1),val2=C((int)(now+i-1),i-1);

				long zz=mul(val1,val2);

				zz=mul(zz,2);

				p=add(p,zz);
			}

		}

		for(int i=1;i<=f;i++)
		{
			if(w>=i-1)
			{
				long now=(w*1L)-((i-1)*1L*(h+1));

				if(now>=0)
				{
					long val1=C(f-1,i-1),val2=get(now,i-1,h==0?1:-1);

					long zz=mul(val1,val2);

					p=add(p,zz);
				}
			}
		}

		for(int i=1;i<=w;i++)
		{
			if(f>=i-1)
			{
				long now=(w*1L)-(i*1L*(h+1));

				if(now>=0)
				{
					long val1=get(now,i,h==0?1:-1),val2=get(f,i-1,1);

					long zz=mul(val1,val2);

					p=add(p,zz);
				}
			}
		}

		long den=pow(q,mod-2),res=mul(p,den);

		out.println(res);out.close();
    }
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Tifuera
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskF solver = new TaskF();
        solver.solve(1, in, out);
        out.close();
    }

    static
    @SuppressWarnings("Duplicates")
    class TaskF {
        private static final long MOD = (long) (1e9 + 7);
        private long[] facts;
        private long[] invFacts;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long f = in.nextInt();
            long w = in.nextInt();
            long h = in.nextInt();

            initFacts();
            initInverseFacts();

            long lower = getAllVariants(f, w, 0);
            long upper = getAllVariants(f, w, h);

            long lowerInverse = getInverse(lower);

            long result = (upper * lowerInverse) % MOD;

            out.println(result);
        }

        private long getAllVariants(long f, long w, long lowerBound) {
            long result = 0;
            for (long numWineStacks = 1; numWineStacks <= w; numWineStacks++) {
                long winesNum = getSol(numWineStacks, w, lowerBound);

                long foodsFirst = getSol(numWineStacks - 1, f, 0);//n-1 food stacks
                long foodSecond = getSol(numWineStacks, f, 0);// n food stacks
                foodSecond = (2 * foodSecond) % MOD;//can start at two pos

                long foodThird = getSol(numWineStacks + 1, f, 0);//n+1 stack

                long foodNum = (foodsFirst + foodSecond + foodThird) % MOD;
                foodNum = (foodNum + MOD) % MOD;

                long curRes = (winesNum * foodNum) % MOD;

                result = (result + curRes) % MOD;
            }

            return result;
        }

        private long getSol(long num, long sum, long lowerBound) {
            if (num < 1) {
                return 0;
            }
            long upSum = sum - lowerBound * num;
            if (upSum < num) {
                return 0;
            }

            return getCnk(upSum - 1, num - 1);
        }

        private long getCnk(long n, long k) {
            long nFact = getFact(n);
            long kFact = getInvFact(k);
            long nkFact = getInvFact(n - k);

            long result = (kFact * nkFact) % MOD;
            result = (nFact * result) % MOD;

            return result;
        }

        private long getFact(long a) {
            return facts[(int) a];
        }

        private long getInvFact(long a) {
            return invFacts[(int) a];
        }

        private long getInverse(long n) {
            return fastPow(n, MOD - 2);
        }

        private long fastPow(long a, long b) {
            if (b == 0) {
                return 1;
            } else if (b % 2 == 0) {
                long t = fastPow(a, b / 2);
                return (t * t) % MOD;
            } else {
                long t = fastPow(a, b - 1);
                return (t * a) % MOD;
            }
        }

        private void initFacts() {
            facts = new long[(int) (1e5 + 1)];
            facts[0] = 1;
            for (int i = 1; i < facts.length; i++) {
                facts[i] = (i * facts[i - 1]) % MOD;
            }
        }

        private void initInverseFacts() {
            invFacts = new long[(int) (1e5 + 1)];
            for (int i = 0; i < invFacts.length; i++) {
                invFacts[i] = getInverse(facts[i]);
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private String[] currentArray;
        private int curPointer;

        public InputReader(InputStream inputStream) {
            reader = new BufferedReader(new InputStreamReader(inputStream));
        }

        public int nextInt() {
            if ((currentArray == null) || (curPointer >= currentArray.length)) {
                try {
                    currentArray = reader.readLine().split(" ");
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                curPointer = 0;
            }
            return Integer.parseInt(currentArray[curPointer++]);
        }

    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Tifuera
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskF solver = new TaskF();
        solver.solve(1, in, out);
        out.close();
    }

    static
    @SuppressWarnings("Duplicates")
    class TaskF {
        private static final long MOD = (long) (1e9 + 7);
        private long[] facts;
        private long[] invFacts;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long f = in.nextInt();
            long w = in.nextInt();
            long h = in.nextInt();

            if (h == 0) {
                out.println(1);
                return;
            }

            initFacts();
            initInverseFacts();

            long lower = getAllVariants(f, w, 0);
            long upper = getAllVariants(f, w, h);

            long lowerInverse = getInverse(lower);

            long result = (upper * lowerInverse) % MOD;

            out.println(result);
        }

        private long getAllVariants(long f, long w, long lowerBound) {
            long result = 0;
            for (long numWineStacks = 1; numWineStacks <= w; numWineStacks++) {
                long winesNum = getSol(numWineStacks, w, lowerBound);

                long foodsFirst = getSol(numWineStacks - 1, f, 0);//n-1 food stacks
                long foodSecond = getSol(numWineStacks, f, 0);// n food stacks
                foodSecond = (2 * foodSecond) % MOD;//can start at two pos

                long foodThird = getSol(numWineStacks + 1, f, 0);//n+1 stack

                long foodNum = (foodsFirst + foodSecond + foodThird) % MOD;
                foodNum = (foodNum + MOD) % MOD;

                long curRes = (winesNum * foodNum) % MOD;

                result = (result + curRes) % MOD;
            }

            return result;
        }

        private long getSol(long num, long sum, long lowerBound) {
            if (num < 1) {
                return 0;
            }
            long upSum = sum - lowerBound * num;
            if (upSum < num) {
                return 0;
            }

            return getCnk(upSum - 1, num - 1);
        }

        private long getCnk(long n, long k) {
            long nFact = getFact(n);
            long kFact = getInvFact(k);
            long nkFact = getInvFact(n - k);

            long result = (kFact * nkFact) % MOD;
            result = (nFact * result) % MOD;

            return result;
        }

        private long getFact(long a) {
            return facts[(int) a];
        }

        private long getInvFact(long a) {
            return invFacts[(int) a];
        }

        private long getInverse(long n) {
            return fastPow(n, MOD - 2);
        }

        private long fastPow(long a, long b) {
            if (b == 0) {
                return 1;
            } else if (b % 2 == 0) {
                long t = fastPow(a, b / 2);
                return (t * t) % MOD;
            } else {
                long t = fastPow(a, b - 1);
                return (t * a) % MOD;
            }
        }

        private void initFacts() {
            facts = new long[(int) (1e5 + 1)];
            facts[0] = 1;
            for (int i = 1; i < facts.length; i++) {
                facts[i] = (i * facts[i - 1]) % MOD;
            }
        }

        private void initInverseFacts() {
            invFacts = new long[(int) (1e5 + 1)];
            for (int i = 0; i < invFacts.length; i++) {
                invFacts[i] = getInverse(facts[i]);
            }
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private String[] currentArray;
        private int curPointer;

        public InputReader(InputStream inputStream) {
            reader = new BufferedReader(new InputStreamReader(inputStream));
        }

        public int nextInt() {
            if ((currentArray == null) || (curPointer >= currentArray.length)) {
                try {
                    currentArray = reader.readLine().split(" ");
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                curPointer = 0;
            }
            return Integer.parseInt(currentArray[curPointer++]);
        }

    }
}