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.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.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.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++]);
        }

    }
}