Go: package main

import (
	"bufio"
			"os"
	"strconv"
	"strings"
	"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	for scanner.Scan() {
		m, _ := strconv.Atoi(scanner.Text())
		if m == 0 {
			break
		}
		ab := make([][]int, 0)
		for i := 0; i < m; i++ {
			scanner.Scan()
			input := strings.Split(scanner.Text(), " ")
			buf := make([]int, len(input))
			for j := range buf {
				buf[j], _ = strconv.Atoi(input[j])
			}
			ab = append(ab, buf)
		}
		dp := make([][]int, 8)
		for i := range dp {
			dp[i] = make([]int, 1001)
		}
		dp[0][0] = 1
		for i := 1; i < m+1; i++ {
			for j := 0; j < 1001; j++ {
				if dp[i-1][j] == 0 {
					continue
				}
				s := j
				for k := ab[i-1][1]; k > -1; k-- {
					if s < 1001 {
						dp[i][s] += dp[i-1][j]
					}
					s += ab[i-1][0]
				}
			}
		}
		scanner.Scan()
		g, _ := strconv.Atoi(scanner.Text())
		for i := 0; i < g; i++ {
			scanner.Scan()
			n, _ := strconv.Atoi(scanner.Text())
			fmt.Println(dp[m][n])
		}
	}
}

C++: #define _USE_MATH_DEFINES
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <cassert>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>
#include <iomanip>
#include <iterator>
 
using namespace std;
 
typedef long long ll;
typedef pair<int,int> Pii;
typedef pair<ll,ll> Pll;
 
#define FOR(i,n) for(int i = 0; i < (n); i++)
#define sz(c) ((int)c.size())

typedef unsigned long long ull;
const int INF = (int)1e8;

int a[7],b[7];
int main(){
	int m;
	while(cin>>m,m){
		FOR(i,m) cin>>a[i]>>b[i];

		int dp[10000] = {};
		dp[0] = 1;
		FOR(i,m){
			for(int j = 1000; j >= 0; j--){
				for(int k = 1; k <= b[i]; k++){
					dp[j + k * a[i]] += dp[j];
				}
			}
		}

		int g; cin>>g;
		FOR(i,g){
			int x; cin>>x;
			cout << dp[x] << endl;
		}
	}
	return 0;
}

C++: //Name: Sum of Cards
//Level: 2
//Category: 動的計画法,DP
//Note:

/*
 * dp[i][j]をi種類目のカードまでを使ってjを作るパターン数とすると，
 *   dp[i][j] = Σ(0≦k≦b_i) dp[i-1][j - a_i*k]
 * となる．
 *
 * 以下のコードでは，iのインデックスを1-originにしてベースケースを簡単にし，また配るDPにして書きやすくしている．
 * オーダーは O(M*G*B)．ただしGは合計値の最大(1000)，Bはカード枚数の最大(10)．
 */
#include <iostream>
#include <vector>

using namespace std;

int dp[8][1001];

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);

    while(true) {
        int M;
        cin >> M;
        if(!M) break;
        dp[0][0] = 1;
        for(int i = 1; i <= M; ++i) {
            int A, B;
            cin >> A >> B;
            for(int j = 0; j < 1001; ++j) dp[i][j] = 0;
            for(int j = 0; j < 1001; ++j) {
                for(int k = 0; k <= B; ++k) {
                    const int next = j + A*k;
                    if(next <= 1000) dp[i][next] += dp[i-1][j];
                }
            }
        }
        int N;
        cin >> N;
        while(N--) {
            int NG;
            cin >> NG;
            cout << dp[M][NG] << endl;
        }
    }
    return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;

int a[8][1001];
int main(){
  int b;
  while(cin>>b,b){
      memset(a,0,sizeof(a));
      for(int c=0;c<b;c++){
	  a[c][0]=1;
	  int d,e;cin>>d>>e;
	  for(int f=0;f<=e;f++){
	      for(int g=max(f*d,1);g<=1000;g++){
		  a[c+1][g]+=a[c][g-f*d];
		  }
	      }
	  }
	  int s;cin>>s;
	  for(int n=0;n<s;n++){
	      int w;cin>>w;
	      cout<<a[b][w]<<endl;
	      }
      }
}

C++: #include <iostream>
using namespace std;
int dp[8][1001] = {0};
int a[7],b[7],m;

void comb() {
  for(int i=0;i<7;i++) {
    for(int j=0;j<1001;j++) {
      dp[i][j] = 0;
    }
  }

  dp[0][0] = 1;

  for(int i=0;i<m;i++) {
    for(int j=0;j<1001;j++) {
      for(int k=0;j-k*a[i]>=0 && k <= b[i];k++) {
        dp[i+1][j] += dp[i][j-k*a[i]];
      }
      //        cout << "dp[" << i+1 << "][" << j << "] = " << dp[i+1][j] << endl;
    }
  }
}

int main() {
  int g,n;
  while(cin >> m) {
    if(m==0) break;
    for(int i=0;i<m;i++) {
      cin >> a[i] >> b[i];
    }
    comb();
    cin >> g;
    for(int i=0;i<g;i++) {
      cin >> n;
      cout << dp[m][n] << endl;
    }
  }
}

C++: #include<iostream>
#include<cstring>
using namespace std;


long long dp[1001];



int main(){
	int m;
	int a[7],b[7];
	while(cin>>m&&m){
		memset(dp,0,sizeof(dp));
		for(int i=0;i<m;i++){
			cin>>a[i]>>b[i];
		}
		dp[0]=1;
		for(int i=0;i<m;i++){
			for(int j=1000;j>=0;j--){
				for(int k=1;k<=b[i];k++){
					if(1000<j+k*a[i])break;
					dp[j+k*a[i]]+=dp[j];
				}
			}
		}
		int g;
		cin>>g;
		for(int i=0;i<g;i++){
			int n;
			cin>>n;
			cout<<dp[n]<<endl;
		}
	}
	return 0;
}

C++: #include <iostream>
#include <cstring>	// require memset
//#include <fstream>	// require freopen

using namespace std;
int memo[1001],a[7],b[7];

void comb (int c, int s, int m)
{

	if (s > 1000 ){
		return;
	} // end if
	if (c == m ){
		memo[s]++; return;
	} // end if
	
	for (int i = 0; i <= b[c]; ++i ){
		comb (c+1, s+a[c]*i, m );
	} // end for
}	

int main()
{
//	cut here before submit 
//	freopen ("testcase.sum_of_card", "r", stdin );
	int m;

	while (cin >> m && m ){
		for (int i = 0; i < m; ++i ){
			cin >> a[i] >> b[i];
		} // end for
		memset (memo, 0, sizeof(memo ) );
		comb (0, 0, m);
		int g;
		cin >> g;
		for (int i = 0; i < g; ++i ){
			int ng;
			cin >> ng;
			int res = memo[ng];
			cout << res << endl;
		} // end for
	} // end loop
		
	return 0;
}

C++: #include<iostream>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<string>
#include<vector>
#include<list>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<cstring>
#include<stack>
#include<functional>
using namespace std;

const int dy[8] = {-1,-1,0,1,1,1,0,-1}, dx[8] = {0,1,1,1,0,-1,-1,-1};

int main(){
	int M;
	while(cin>>M,M){
		int dp[1001] = {}; dp[0] = 1;
		for(int k=0;k<M;k++){
			int A,B; cin>>A>>B;
			for(int i=1000;i>=0;i--){
				for(int j=1;j<=B && i+A*j<=1000;j++){
					dp[i+A*j] += dp[i];
				}
			}
		}
		int G; cin>>G;
			for(int i=0;i<G;i++){
				int N; cin>>N;
				printf("%d\n",dp[N]);
			}
	}
	return 0;
}

C++: #include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int main(void)
{
	int m,i,j,k,a[7],b[7],g,n[10],dp[8][1001];
	while(1)	{
		scanf("%d",&m);
		if(m==0)	break;
		for(i=0;i<m;i++)	{
			scanf("%d %d",&a[i],&b[i]);
		}
		scanf("%d",&g);
		for(i=0;i<g;i++)	scanf("%d",&n[i]);
		for(i=0;i<=m;i++)	{
			for(j=0;j<=1000;j++)	dp[i][j]=0;
		}
		
		dp[0][0]=1;
		for(i=0;i<m;i++)	{
			for(j=0;j<=1000;j++)	{
				for(k=0;k<=b[i];k++)	{
					if(j+k*a[i]<=1000)	{
						dp[i+1][j+k*a[i]]+=dp[i][j];
					}
				}
			}
		}
		for(i=0;i<g;i++)	{
			printf("%d\n",dp[m][n[i]]);
		}
	}
	return 0;
}

C++: #include <iostream>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
#define fr first
#define sc second
using namespace std;

int n,p,dp[1001];
typedef pair<int,int> iP;
vector <iP> v;

void rec(int idx,int sum){
  if(sum > 1000) return;
  if(idx == n){ dp[sum]++; return; }
  for(int i=0;i<=v[idx].sc;i++){
    rec(idx+1,sum + (v[idx].fr * i));
  }
}

int main(){
  int m;
  while(cin >> n,n){
    v.resize(0);  memset(dp,0,sizeof(dp));
    for(int i=0;i<n;i++){
      int t,m; cin >> t >> m; v.push_back(iP(t,m));
    }
    cin >> m;
    rec(0,0);
    for(int i=0;i<m;i++){
      cin >> p;
      cout << dp[p] << endl;
    }
  }
}