Problem:
Problem H:
Vending Machine
There has been marketing warfare among beverage vendors, and they have been working hard for in-
crease of their sales. The Kola-Coqua Company is one of the most successful vendors among those:
their impressive advertisements toward the world has brought the overwhelming market share of their
representative product called Koque.
This time, Kola-Coqua is focusing on vending machines. They think cusomters will be more pleasant as
the machines respond more quickly, so they have improved many parts of the machines.
In particular, they have developed a new device of change return. The new device can give one or more
kinds of coins at a time (in a single operation), although it can give only one coin for each kind at once.
For example, suppose there are 500-yen, 100-yen, 50-yen and 10-yen coins, change of 6540 yen can be
made by four operations of giving 500-yen and 10-yen coins and nine operations of giving 500-yen coins.
In conclusion, 6540 yen can be returned by thirteen operations. It is supposed that the new device allows
customers to make their purchase more quickly and so helps Kola-Coqua’s market share grow up.
However, the project leader says “No, it’s not optimal yet.” His suggesion is as follows: the real opti-
mization is to minimize the number of operations. For example, change of 6540 yen should be made
with ten of 500-yen coins, ten of 100-yen coins, ten of 50-yen coins, and four of 10-yen coins. This way,
6540 yen can be returned only with ten operations. This allows full speed-up in giving back change, even
though it sometimes results in a huge amount of coins.
Given which kinds of coins are available and how much change should be given back, you are to write a
program that calculates the minimum number of operations according to the above suggestion. You may
assume that there are enough amount of coins inside the vending machines.
Input
The input consists of multiple data sets. Each dataset is described by two lines. The first line contains
N
(
N
≤ 10) and
M
(
M
≤ 100000) indicating the number of kinds of coins and the amount of change to be
made, respectively. The second line contains N integers representing the value of each kind of coin.
The input is terminated by a dataset of
N
=
M
= 0. This dataset must not be processed.
Output
For each dataset, output in a line the minimum number of operations needed to give back exactly the
specified amount of change.
Sample Input
6 330
1 5 10 50 100 500
7 127
1 2 4 8 16 32 64
2 10000
1000 2000
0 0
Output for the Sample Input
2
1
4

Submitted solutions:

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

const int N = 100005;
bitset<N> bs;

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n, m;
    while (cin >> n >> m, n + m) {
        vector<int> a(n);
        for (int i = 0; i < n; ++i) {
            cin >> a[i];
        }

        auto slv = [&](int x) -> bool {
            bs &= (bs << N);
            priority_queue<int, vector<int>, greater<>> pq;
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < x; ++j) {
                    pq.push(a[i]);
                }
            }
            vector<int> v;
            while (!pq.empty()) {
                int p = pq.top();
                if (p > m) break;
                int cnt = 0;
                while (!pq.empty() and pq.top() == p) {
                    pq.pop();
                    cnt += 1;
                }
                while (cnt >= 3) {
                    cnt -= 2;
                    if (p + p <= m) pq.push(p + p);
                }
                for (int i = 0; i < cnt; ++i) {
                    v.push_back(p);
                }
            }
            bs.set(0);
            for (int i : v) {
                bs |= (bs << i);
            }
            return bs[m];
        };

        int l = -1, r = m + 1;
        while (r - l > 1) {
            int mid = (l + r) / 2;
            if (slv(mid)) r = mid;
            else l = mid;
        }
        cout << r << "\n";
    }
}
accuracy: 1
time_ms: 1080
memory_kb: 7048
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

const int INF = 19191919;

int main(){
    int n,m;
    while(scanf(" %d %d", &n, &m),n){
        vector<int> a(n);
        rep(i,n) scanf(" %d", &a[i]);

        vector<int> c(1<<n);
        rep(mask,1<<n){
            rep(i,n)if(mask>>i&1) c[mask] += a[i];
        }

        vector<int> dp(m+1,INF);
        dp[0] = 0;
        rep(i,m){
            rep(mask,1<<n){
                if(i+c[mask]>m) continue;
                dp[i+c[mask]] = min(dp[i+c[mask]], dp[i]+1);
            }
        }
        printf("%d\n", dp[m]);
    }
    return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 3512
final_rank: 17

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;

int dp[111111],n,m,a[111];

int main(){
  while(cin>>n>>m,n){
    vector<int>v;
    r(i,n)cin>>a[i];
    r(i,(1<<n)){
      int f=0;
      r(j,n)if(i&(1<<j))f+=a[j];
      v.push_back(f);
    }
    r(i,111111)dp[i]=1e9;
    dp[0]=0;
    r(i,m+1){
      r(j,(1<<n)){
        if(i+v[j]>=m+100)continue;
        dp[i+v[j]]=min(dp[i+v[j]],dp[i]+1);
      }
    }
    cout<<dp[m]<<endl;
  }
}
accuracy: 1
time_ms: 500
memory_kb: 3540
final_rank: 16

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define int long long
#define all(v) begin(v), end(v)
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define reps(i, s, n) for(int i = (int)(s); i < (int)(n); i++)
#define min(...) min({__VA_ARGS__})
#define max(...) max({__VA_ARGS__})

template<class T1, class T2> void chmin(T1 &a, T2 b){if(a>b)a=b;}
template<class T1, class T2> void chmax(T1 &a, T2 b){if(a<b)a=b;}

using pint = pair<int, int>;
using tint = tuple<int, int, int>;
using vint = vector<int>;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

int coin[10];
int change[1<<10];
int dp[100010];

signed main()
{
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  int N, M;
  while(cin >> N >> M, N || M) {
    rep(i, N) cin >> coin[i];
    rep(i, 1<<N) {
      int c = 0;
      rep(j, N) if((i>>j)&1) c += coin[j];
      change[i] = c;
    }
    fill(dp, dp + 100010, inf);
    dp[0] = 0;
    rep(i, 1<<N) {
      for(int j = 0; j+change[i] <= M; j++) {
	chmin(dp[j+change[i]], dp[j] + 1);
      }
    }
    cout << dp[M] << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 3808
final_rank: 14

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int a[15], n, w; bool dp[100020];
bool knapsack(vector<int>x) {
	for (int i = 1; i < 100020; i++)dp[i] = false; dp[0] = true;
	for (int i = 0; i < (int)x.size(); i++) {
		for (int j = w - x[i]; j >= 0; j--) {
			if (dp[j] == true)dp[j + x[i]] = true;
		}
	}
	return dp[w];
}
bool solve(int r) {
	vector<int>J;
	for (int i = 0; i < n; i++) {
		int R = r, t = 0;
		while (R >= (1 << t)) {
			R -= (1 << t); t++;
			J.push_back(a[i] * (1 << (t - 1)));
		}
		if (R >= 1)J.push_back(a[i] * R);
	}
	return knapsack(J);
}
int main() {
	while (true) {
		cin >> n >> w; if (n == 0 && w == 0)break;
		for (int i = 0; i < n; i++)cin >> a[i];
		int L = 1, R = w + 10, M;
		while (true) {
			M = (L + R) / 2;
			bool p1 = solve(M), p2 = solve(M - 1);
			if (p1 == true && p2 == false) { cout << M << endl; break; }
			if (p2 == true)R = M;
			if (p1 == false)L = M;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 1490
memory_kb: 3248
final_rank: 19

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>

using namespace std;

bool** table;

void func(int N,int M){
	int coin[N],second_coin[1024],index = 0;

	for(int i = 0; i < N; i++){
		for(int k = 0; k < M+1; k++)table[i][k] = false;
	}

	for(int i = 0; i < N; i++){
		scanf("%d",&coin[i]);
	}

	table[0][coin[0]] = true;

	for(int i = 1; i < N; i++){

		for(int k = 1; k < coin[i];k++){
			if(table[i-1][k] == true)table[i][k] = true;
		}

		table[i][coin[i]] = true;

		for(int k = coin[i]+1; k <= M; k++){
			if(table[i-1][k] == true || table[i-1][k-coin[i]] == true)table[i][k] = true;
		}
	}

	for(int i = 1; i <= M; i++){
		if(table[N-1][i] == true){
			second_coin[index++] = i;
		}
	}

	int dp[M+1];
	for(int i = 1; i <= M; i++)dp[i] = 2000000000;

	dp[0] = 0;

	for(int i = 1; i <= M; i++){
		for(int k = 0; k < index; k++){
			if(i >= second_coin[k]){
				dp[i] = min(dp[i],dp[i-second_coin[k]] + 1);
			}
		}
	}

	printf("%d\n",dp[M]);

}


int main(){

	int N,M;

	table = new bool*[10];
	for(int i = 0; i < 10; i++){
		table[i] = new bool[100001];
	}

	while(true){
		scanf("%d %d",&N,&M);
		if(N == 0 && M == 0)break;

		func(N,M);
	}

    return 0;
}
accuracy: 1
time_ms: 330
memory_kb: 3984
final_rank: 15

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
#define MAX_N 10
#define MAX_M 100000
#define INF 1e9
 
int N,M,coin[MAX_N];
int dp[MAX_M+1];
 
bool c(int x){
    memset(dp,-1,sizeof(dp));
    dp[0] = 0;
    for(int i = 0 ; i < N ; i++){
	for(int j = 0 ; j <= M ; j++){
	    if(dp[j] >= 0){
		dp[j] = x;
	    }else if(j < coin[i] || dp[j-coin[i]] <= 0){
		dp[j] = -1;
	    }else{
		dp[j] = dp[j-coin[i]]-1;
	    }
	}
    }
    return (dp[M] >= 0);
}
 
int main(){
    while(cin >> N >> M,(N|M)){
	for(int i = 0 ; i < N ; i++){
	    cin >> coin[i];
	}
	sort(coin,coin+N);
	int l = 0, r = M+1;
	while(r-l > 0){
	    int m = (l + r) / 2;
	    if(c(m)){
		r = m;
	    }else{
		l = m+1;
	    }
	}
	cout << r << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 3476
final_rank: 13

code_snippet: #include <iostream>
#define N_MAX 10
#define M_MAX 100001
#define f first
#define s second
using namespace std;
typedef pair<bool,int> P;
int Binary_Search();
bool DP_Check(int);
int N,M,c[N_MAX];

int main(){
  while(1){
    cin>>N>>M;
    if(!N&&!M) break;
    for(int i=0;i<N;i++) cin>>c[i];
    cout<<Binary_Search()<<endl;
  }
  return 0;
}

int Binary_Search(){
  int l=0,r=M+1,m;
  while(l<r){
    m=(l+r)/2;
    DP_Check(m)?r=m:l=m+1;
  }
  return l;
}

bool DP_Check(int k){
  P dp[M+1];
  for(int i=0;i<=M;i++) dp[i].f=false,dp[i].s=0; 
  dp[0].f=true;
  for(int i=0;i<N;i++){
    for(int j=c[i];j<=M;j++){
      if(dp[j].f) continue;
      if(dp[j-c[i]].f&&dp[j-c[i]].s<k){
	dp[j].f=true;
	dp[j].s=dp[j-c[i]].s+1;
      }
    }
    for(int j=0;j<=M;j++) dp[j].s=0;
  }
  if(dp[M].f==true) return true;
  return false;
}
accuracy: 1
time_ms: 260
memory_kb: 1940
final_rank: 8

code_snippet: #include <iostream>
#define N_MAX 10
#define M_MAX 100001
#define f first
#define s second
using namespace std;
typedef pair<bool,int> P;
int Binary_Search();
bool DP_Check(int);
int N,M,c[N_MAX];

int main(){
  while(1){
    cin>>N>>M;
    if(!N&&!M) break;
    for(int i=0;i<N;i++) cin>>c[i];
    cout<<Binary_Search()<<endl;
  }
  return 0;
}

int Binary_Search(){
  int l=0,r=M+1,m;
  while(l<r){
    m=(l+r)/2;
    DP_Check(m)?r=m:l=m+1;
  }
  return l;
}

bool DP_Check(int k){
  P dp[M+1];
  for(int i=0;i<=M;i++) dp[i].f=false,dp[i].s=0; 
  dp[0].f=true;
  for(int i=0;i<N;i++){
    for(int j=c[i];j<=M;j++){
      if(dp[j].f) continue;
      if(dp[j-c[i]].f&&dp[j-c[i]].s</*=*/k){
	//	if(dp[j-c[i]].s==k) break;
	dp[j].f=true;
	dp[j].s=dp[j-c[i]].s+1;
      }
    }
    for(int j=0;j<=M;j++) dp[j].s=0;
  }
  if(dp[M].f==true) return true;
  return false;
}
accuracy: 1
time_ms: 270
memory_kb: 1936
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#define INF 1000000000;
using namespace std;
int n,m,a[11];
vector <int> coin;
int used[11];
void mk_coin(int sum,int k){
  for(int i=k;i<n;i++) {
    if(used[i]==1) continue;
    used[i]=1;
    coin.push_back(sum+a[i]);
    mk_coin(sum+a[i],i+1);
    used[i] = 0;
  }
}

int main() {
  while(1){
    cin >> n >> m;
    if(n==0&&m==0) break;
    coin.clear();
    for(int i=0;i<n;i++)cin >> a[i];
    mk_coin(0,0);
    
    int dp[100010]={};
    for(int i=1;i<=m;i++) dp[i] = INF;
    for(int i=0;i<coin.size();i++)
      for(int j=0;j<=m-coin[i];j++) dp[j+coin[i]] = min(dp[j]+1,dp[j+coin[i]]); 
    cout <<dp[m]<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 390
memory_kb: 1616
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#define INF 1000000000;
using namespace std;
int n,m,a[11];
vector <int> coin;
int used[11];
void mk_coin(int sum,int k){
  for(int i=k;i<n;i++) {
    if(used[i]==1) continue;
    used[i]=1;
    coin.push_back(sum+a[i]);
    mk_coin(sum+a[i],i+1);
    used[i] = 0;
  }
}
 
int main() {
  while(1){
    cin >> n >> m;
    if(n==0&&m==0) break;
    coin.clear();
    for(int i=0;i<n;i++)cin >> a[i];
    mk_coin(0,0);
    
    int dp[100010]={};
    for(int i=1;i<=m;i++) dp[i] = INF;
    for(int i=0;i<coin.size();i++)
      for(int j=0;j<=m-coin[i];j++) dp[j+coin[i]] = min(dp[j]+1,dp[j+coin[i]]); 
    cout <<dp[m]<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 380
memory_kb: 1616
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#define INF 1000000000;
using namespace std;
int n,m,a[11];
vector <int> coin;
int used[11];
void saiki(int sum,int k){
  for(int i=k;i<n;i++) {
    if(used[i]==1) continue;
    used[i]=1;
    coin.push_back(sum+a[i]);
    saiki(sum+a[i],i+1);
    used[i] = 0;
  }
}

int main() {
  while(1){
    cin >> n >> m;
    if(n==0&&m==0) break;
    coin.clear();
    for(int i=0;i<n;i++)cin >> a[i];
    saiki(0,0);

    int dp[100010]={};
    for(int i=1;i<=m;i++) dp[i] = INF;
    for(int i=0;i<coin.size();i++)
      for(int j=0;j<=m;j++)
	for(int k=1;j+coin[i]*k<=m && dp[j+coin[i]*k]>dp[j]+k;k++) dp[j+coin[i]*k] = dp[j]+k; 
    cout <<dp[m]<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 1616
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
int n,m,a[10];
int dp[100001];

int main(){
  while(1){
    cin>>n>>m;
    if(n==0&&m==0)break;
    for(int i=0;i<n;i++)cin>>a[i];
    
    int L=1,R=m,M;
    while(L<R){
      M=(L+R)/2;
      memset(dp,-1,sizeof(dp));
      dp[0]=0;
      for(int i=0;i<n;i++){
        for(int j=1;j<=m;j++){          
          if(dp[j]==-1){
            if(j-a[i]>=0&&dp[j-a[i]]!=-1&&dp[j-a[i]]<M)
              dp[j]=dp[j-a[i]]+1;
          }else{
            dp[j]=0;
          }
        }
      }
      if(dp[m]==-1)L=M+1;
      else R=M;
    }
    cout<<L<<endl;    
  }
  return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 1556
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N, M;
int A[10];
int dp[100001];

bool Check(int k)
{
  memset(dp, -1, sizeof(int) * (M + 1));
  dp[0] = 0;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j <= M; j++) {
      if(dp[j] >= 0) {
        dp[j] = k;
      } else if(j < A[i] || dp[j - A[i]] <= 0) {
        dp[j] = -1;
      } else {
        dp[j] = dp[j - A[i]] - 1;
      }
    }
  }
  return(dp[M] >= 0);
}


int main()
{
  while(cin >> N >> M, N) {
    for(int i = 0; i < N; i++) {
      cin >> A[i];
    }
    int low = 0, high = M / *min_element(A, A + N);
    while(high - low > 0) {
      int mid = (low + high) >> 1;
      if(Check(mid)) high = mid;
      else low = mid + 1;
    }
    cout << low << endl;
  }
}
accuracy: 1
time_ms: 200
memory_kb: 1556
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N, M;
int A[10];
int dp[100001];

bool Check(int k)
{
  memset(dp, -1, sizeof(dp));
  dp[0] = 0;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j <= M; j++) {
      if(dp[j] >= 0) {
        dp[j] = k;
      } else if(j < A[i] || dp[j - A[i]] <= 0) {
        dp[j] = -1;
      } else {
        dp[j] = dp[j - A[i]] - 1;
      }
    }
  }
  return(dp[M] >= 0);
}


int main()
{
  while(cin >> N >> M, N) {
    for(int i = 0; i < N; i++) {
      cin >> A[i];
    }
    int low = 0, high = M / *min_element(A, A + N);
    while(high - low > 0) {
      int mid = (low + high) >> 1;
      if(Check(mid)) high = mid;
      else low = mid + 1;
    }
    cout << low << endl;
  }
}
accuracy: 1
time_ms: 210
memory_kb: 1556
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N, M;
int A[10];
int dp[100001];

bool Check(int k)
{
  fill_n(dp, 100001, -1);
  dp[0] = 0;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j <= M; j++) {
      if(dp[j] >= 0) {
        dp[j] = k;
      } else if(j < A[i] || dp[j - A[i]] <= 0) {
        dp[j] = -1;
      } else {
        dp[j] = dp[j - A[i]] - 1;
      }
    }
  }
  return(dp[M] >= 0);
}


int main()
{
  while(cin >> N >> M, N) {
    for(int i = 0; i < N; i++) {
      cin >> A[i];
    }
    int low = 0, high = M / *min_element(A, A + N);
    while(high - low > 0) {
      int mid = (low + high) >> 1;
      if(Check(mid)) high = mid;
      else low = mid + 1;
    }
    cout << low << endl;
  }
}
accuracy: 1
time_ms: 230
memory_kb: 1548
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N, M;
int A[10];
int dp[100001];

bool Check(int k)
{
  fill_n(dp, 100001, -1);
  dp[0] = 0;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j <= M; j++) {
      if(dp[j] >= 0) {
        dp[j] = k;
      } else if(j < A[i] || dp[j - A[i]] <= 0) {
        dp[j] = -1;
      } else {
        dp[j] = dp[j - A[i]] - 1;
      }
    }
  }
  return(dp[M] >= 0);
}


int main()
{
  while(cin >> N >> M, N) {
    for(int i = 0; i < N; i++) {
      cin >> A[i];
    }
    sort(A, A + N, greater< int >());
    int low = 0, high = M;
    while(high - low > 0) {
      int mid = (low + high) >> 1;
      if(Check(mid)) high = mid;
      else low = mid + 1;
    }
    cout << low << endl;
  }
}
accuracy: 1
time_ms: 270
memory_kb: 1568
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N, M;
int A[10];
int dp[100001];

bool Check(int k)
{
  fill_n(dp, 100001, -1);
  dp[0] = 0;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j <= M; j++) {
      if(dp[j] >= 0) {
        dp[j] = k;
      } else if(j < A[i] || dp[j - A[i]] <= 0) {
        dp[j] = -1;
      } else {
        dp[j] = dp[j - A[i]] - 1;
      }
    }
  }
  return(dp[M] >= 0);
}


int main()
{
  while(cin >> N >> M, N) {
    for(int i = 0; i < N; i++) {
      cin >> A[i];
    }
    sort(A, A + N);
    int low = 0, high = M;
    while(high - low > 0) {
      int mid = (low + high) >> 1;
      if(Check(mid)) high = mid;
      else low = mid + 1;
    }
    cout << low << endl;
  }
}
accuracy: 1
time_ms: 230
memory_kb: 1564
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N, M;
int A[10];
int dp[100001];

bool Check(int k)
{
  fill_n(dp, 100001, -1);
  dp[0] = 0;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j <= M; j++) {
      if(dp[j] >= 0) {
        dp[j] = k;
      } else if(j < A[i] || dp[j - A[i]] <= 0) {
        dp[j] = -1;
      } else {
        dp[j] = dp[j - A[i]] - 1;
      }
    }
  }
  return(dp[M] >= 0);
}


int main()
{
  while(cin >> N >> M, N) {
    for(int i = 0; i < N; i++) {
      cin >> A[i];
    }
    int low = 0, high = M;
    while(high - low > 0) {
      int mid = (low + high) >> 1;
      if(Check(mid)) high = mid;
      else low = mid + 1;
    }
    cout << low << endl;
  }
}
accuracy: 1
time_ms: 230
memory_kb: 1548
final_rank: 4

code_snippet: #define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>
#include <cctype>
#include <utility>
 
using namespace std;
 
typedef long long ll;
typedef pair <int,int> P;
typedef pair <int,P > PP;
 
int tx[] = {0,1,0,-1};
int ty[] = {-1,0,1,0};
 
static const double EPS = 1e-8;

int dp[1<<20];

int main(){
  int num_of_coins;
  int change;
  while(~scanf("%d %d",&num_of_coins,&change)){
    if(num_of_coins == 0 && change == 0) break;
    memset(dp,0x3f,sizeof(dp));

    vector<int> coins;
    for(int coin_i = 0; coin_i < num_of_coins; coin_i++){
      int price;
      scanf("%d",&price);
      coins.push_back(price);
    }

    int sum[1<<12] = {};
    for(int S = 0; S < (1<<num_of_coins); S++){
      for(int coin_i = 0; coin_i < num_of_coins; coin_i++){
        if(!(S & (1<<coin_i))) continue;
        sum[S] += coins[coin_i];
      }
    }

    dp[0] = 0;
    for(int S = 0; S < (1<<num_of_coins); S++){
      for(int prev = 0; prev + sum[S] <= change; prev++){
        int next = prev + sum[S];
        dp[next] = min(dp[prev] + 1,dp[next]);
      }
    }

    printf("%d\n",dp[change]);
  }
}
accuracy: 1
time_ms: 400
memory_kb: 5324
final_rank: 18