За решаването на задачата въвеждаме целевата функция F( s , k ), която ни дава броя на начините за получаване на сумата S, и чрез която можем да проверим дали дадена сума S може да се получи при използването на  първите k монети: c0, c1,.....c k-1. В приложената реализация не можем да подходим директно към целта, тъй като конфигурациите нямат явна наредба, но лесно можем да въведем такава, ако изискаме монетите  да бъдат наредени по големина в нарастващ ред. За задачата са в сила  няколко общи случая :
               1.  
F( s , k ) = 1+ F( s-c k , k-1 ) + F( s , j ), j = max[cu<c k]   l:c 1 = s;  В този случай формулата от говаря на случая когато съществува монета със стойност S.
                2. F( s , k )F( s-ck , k-1 ) + F( s , j ), j = max[cu<c k]  иначе;  Формулата отговаря на общия случай, когато не същестува  монета със стойност S. Имаме две взаимноизкючващи се възможности:
                        1) k - тата монета учасва в сумата. Броят на тези конфигурации се дава от първото събираемо.    
                        2) k - тата монета не учасва в сумата. Броят на тези конфигурации се дава от второто събираемо.    
       

#include <cstdlib>                                                                                            
#include <fstream>                                   
#include <cstring>                                                                                                   
#include <iostream>
using namespace std;

#define MAXCOINS  1000                                                                          
#define MAXSUM 1000   

ifstream fin("file.inp",ios::in);                                                         
ofstream fout("file.out",ios::out);  
unsigned long F[MAXSUM][MAXSUM];    /*Целева функция*/
unsigned coins[MAXCOINS];
unsigned sum;
unsigned n;

int compare(const void *, const void *);        
/*qsort( ) Сортира монетите в нарастващ ред */
void init(void);                                               /*Инициализираща функция */         
unsigned long count(int , int );                       
/*Проверява дали дадена сума S може да се получи*/

int main(){
    while(fin >>sum >>n){
        for(int i=0; i<n; i++)
            fin >>coins[i];
    }
    init();
    qsort( coins,n,sizeof(int), compare);
    if(!count(sum,n-1))fout<<"No" <<endl;
    system("PAUSE");
    return 0;
}
int compare(const void *i, const void *j){
    return *(int *)i - *(int *)j;
}
void init(void){
   /
* Нулиране на целевата функция*/
    unsigned i,j;
    for( i=0;  i<=sum; i++)
        for(j=0; j<=sum; j++)
            F[i][j]=0;
}
unsigned long count(int sum, int k){
    unsigned j;
    if(sum <=0 || k < 0)return 0;
    if(F[sum][k]>0) return F[sum][k];
    else{
        if(coins[k]==(unsigned)sum){
           F[sum][k] = 1;
            fout <<"Yes" <<endl;
            exit(1);
        }
        F[sum][k]+=count(sum-coins[k], k-1);
        j = k;
        while(coins[j]==coins[k])j--;
        F[sum][k]+=count(sum,j);
    }
    return F[sum][k];
}