Problem:
Score : 300 points

Problem Statement

Tak has N cards. On the i-th (1 \leq i \leq N) card is written an integer x_i.
He is selecting one or more cards from these N cards, so that the average of the integers written on the selected cards is exactly A.
In how many ways can he make his selection?

Constraints

1 \leq N \leq 50

1 \leq A \leq 50

1 \leq x_i \leq 50

N,\,A,\,x_i are integers.

Partial Score

200 points will be awarded for passing the test set satisfying 1 \leq N \leq 16.

Input

The input is given from Standard Input in the following format:

N A
x_1 x_2 ... x_N

Output

Print the number of ways to select cards such that the average of the written integers is exactly A.

Sample Input 1

4 8
7 9 8 9

Sample Output 1

5

The following are the 5 ways to select cards such that the average is 8:

Select the 3-rd card.

Select the 1-st and 2-nd cards.

Select the 1-st and 4-th cards.

Select the 1-st, 2-nd and 3-rd cards.

Select the 1-st, 3-rd and 4-th cards.

Sample Input 2

3 8
6 6 9

Sample Output 2

0

Sample Input 3

8 5
3 6 2 8 7 6 5 9

Sample Output 3

19

Sample Input 4

33 3
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3

Sample Output 4

8589934591

The answer may not fit into a 32-bit integer.

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections;
using System.IO;
using System.Linq;

namespace CompetitiveProgramming
{

  class Solve
  {
    const int INF = (int)(1e9) + 10;

    ulong N, A;
    ulong[] x;
    
    ulong[,,] dp = new ulong[3000, 51, 51];

    ulong rec(ulong sum, ulong selected, ulong index) {
      ulong ret = 0;
      ulong t = 0;

      if (index >= N)
      {
        return 0;
      }

      if (dp[sum, selected, index] > 0) 
      {
        return dp[sum, selected, index];
      }


      if ((double)(sum + x[index]) / (selected + 1) == A)
      {
        t++;
      }

      ret += rec(sum, selected, index + 1);
            
      ret += rec(sum + x[index], selected + 1, index + 1);
      return dp[sum, selected, index] = (ret + t);
    }

    private void Main()
    {
      ulong[] NA = Console.ReadLine().Split().Select(ulong.Parse).ToArray();
      N = NA[0];  A = NA[1];
      x = Console.ReadLine().Split().Select(ulong.Parse).ToArray();
      Console.WriteLine(rec(0, 0, 0)
);    }

    public Solve()
    {
      Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
      Main();
      Console.Out.Flush();
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      new Solve();
    }
  }
}