Problem:
ビンゴ

問題

あるプログラミングコンテストでは,競技後の懇親会でビンゴゲームをする習わしがある．しかし,このビンゴゲームで使うビンゴカードは少々特殊で,以下の条件に従って作成される．

ビンゴカードは N 行 N 列のマス目に区切られており，各マス目には正整数が１つずつ書かれている．それらの整数は全て異なる．

マス目に書かれている整数は 1 以上 M 以下である．

ビンゴカードに書かれているN×N個の整数の合計は S である．

どの列を見たときも，上から下に向かって整数は昇順に並んでいる．

どのマス目の整数も，そのマス目より左の列のどの整数よりも大きい．

以下は， N = 5, M = 50, S = 685 のときのビンゴカードの例である．

懇親会のために上の条件を満たすビンゴカードをできるだけたくさん作りたい．ただし，同一のカードを2枚以上作ってはならない．作ることができるビンゴカードの枚数の最大値を 100000 で割った余りを出力するプログラムを作成せよ．

入力

入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．

入力は1行からなり, その行にはビンゴカードのサイズ N (1≤N≤7), マス目に書かれている整数の上限 M (1≤M≤2000),ビンゴカードに書かれている整数の合計 S (1≤S≤3000) を表す3つの正整数が空白区切りで書かれている．ただし, 与えられるどの入力データにおいても，条件を満たすビンゴカードを1枚以上作ることができる．

N, M, S が 0 のとき入力の終了を示す. データセットの数は 5 を超えない．

出力

データセットごとに, 作ることができるビンゴカードの枚数の最大値を 100000 で割った余りを1行に出力せよ．

入出力例

入力例

3 9 45
3 100 50
5 50 685
0 0 0

出力例

1
7
74501

3つ目の入力例に対して，作ることができるビンゴカードの枚数の最大値は 642499974501 であるので， 100000 で割った余りの 74501 を出力する．

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in C++ (judge verdict: Time Limit Exceeded)

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<string>
#include<stack>
#include<cstdio>
#include<cmath>
using namespace std;
  
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef pair<int,P> P1;
  
#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define rep(i,x) for(int i=0;i<x;i++)
#define rep1(i,x) for(int i=1;i<=x;i++)
#define rrep(i,x) for(int i=x-1;i>=0;i--)
#define rrep1(i,x) for(int i=x;i>0;i--)
#define sor(v) sort(v.begin(),v.end())
#define rev(s) reverse(s.begin(),s.end())
#define lb(vec,a) lower_bound(vec.begin(),vec.end(),a)
#define ub(vec,a) upper_bound(vec.begin(),vec.end(),a)
#define uniq(vec) vec.erase(unique(vec.begin(),vec.end()),vec.end())
#define min_3(a,b,c) min(a,min(b,c))
#define max_3(a,b,c) max(a,max(b,c))
#define mp1(a,b,c) P1(a,P(b,c))
#define pque(a) priority_queue<a>
#define rpque(a) priority_queue<a,vector<a>,greater<a>>
  
const int INF=1000000000;
const int dir_4[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
const int dir_8[8][2]={{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
const int kaijou[10]={1,1,2,6,24,120,720,5040,40320,362880};
  
int main(){
    while(1){
        int n,m,s;
        scanf("%d%d%d",&n,&m,&s); if(n == 0 && m == 0 && s == 0)break;
          
        static int dp[2002][3002] = {};
        rep(i,2002){
            rep(j,3002){
                if(j == 0)dp[i][j] = 1;
                else dp[i][j] = 0;
            }
        }
    	
    	int l = 0,r;
          
        rep1(i,n*n){
        	l += i;
        	r = s;
        	for(int j = i+1;j <= n*n; j++){
        		r -= j;
        	}
        	for(int j = r;j >= l;j --){
                rep1(k,min(m,j)){
                    dp[k][j] = dp[k-1][j-k];
                    if(dp[k][j] >= 100000)dp[k][j] %= 100000;
                }
        		for(int k = min (m,j)+1;k <= m ; k ++){
        			dp[k][j] = 0;
        		}
                dp[0][j] = 0;
            }
        	for(int j = l-i;j < l;j ++){
        		rep1(k,m){
        			dp[k][j] = 0;
        		}
        		dp[0][j] = 0;
        	}
        	for(int j = l;j <= r;j ++){
                rep1(k,m){
                    dp[k][j] += dp[k-1][j];
                    if(dp[k][j] >= 100000)dp[k][j] %= 100000;
                }
            }
        }
          
        printf("%d\n",dp[m][s]);
    }
}