#include #include #include #define FOR(i,n) for(int i = 0; i < n; i++) #define FORD(i,n) for(i = 0; i < n; i++) // Tento FOR přijímá pouze deklarovanou proměnou typedef unsigned int uint; bool *****batoh; unsigned char K,N; uint surovin[5]; uint (*recept)[5]; int main(void){ scanf(" %u",&K); FOR(i,K){ scanf(" %u",&surovin[i]); } for(int i = K; i < 5; i++) surovin[i] = 0; scanf(" %u",&N); recept = (uint(*)[5]) malloc(sizeof(uint)*5*(N)); FOR(i,N){ FOR(j,K){ scanf(" %u",&recept[i][j]); } } batoh = malloc(sizeof(bool ****) * (surovin[0]+1)); FOR(i,surovin[0]+1){ batoh[i] = malloc(sizeof(bool ***) * (surovin[1]+1)); FOR(j, (surovin[1]+1)){ batoh[i][j] = malloc(sizeof(bool **) * (surovin[2]+1)); FOR(k, (surovin[2]+1)){ batoh[i][j][k] = malloc(sizeof(bool *) * (surovin[3]+1)); FOR(l, (surovin[3]+1)){ batoh[i][j][k][l] = malloc(sizeof(bool ) * (surovin[4]+1)); FOR(m, (surovin[4]+1)) batoh[i][j][k][l][m] = false; } } } } uint val[5]; uint celkem_surovin = 0; uint odecet[5]; FOR(i,K) celkem_surovin += surovin[i]; unsigned int kroku = 0; batoh[0][0][0][0][0] = true; FOR(cislo_receptu,N){ FORD(kroku,celkem_surovin+1){ FORD(odecet[0],kroku+1){ if(odecet[0] > surovin[0]) break; FORD(odecet[1], kroku - odecet[0] +1){ if(odecet[1] > surovin[1]) break; FORD(odecet[2], kroku - odecet[0] - odecet[1]+1){ if(odecet[2] > surovin[2]) break; FORD(odecet[3],kroku - odecet[0] - odecet[1] - odecet[2]+1){ if(odecet[3] > surovin[3]) break; odecet[4] = kroku - odecet[0] - odecet[1] - odecet[2] - odecet[3]; if(odecet[4] <= surovin[4] && batoh[surovin[0] - odecet[0]] [surovin[1] - odecet[1]] [surovin[2] - odecet[2]] [surovin[3] - odecet[3]] [surovin[4] - odecet[4]]){ FOR(j,5){ val[j] = surovin[j] - odecet[j] + recept[cislo_receptu][j]; if(val[j] > surovin[j]) goto dalsi; } batoh[val[0]][val[1]][val[2]][val[3]][val[4]] = true; dalsi:; } } } } } } } // TODO procházení do šířky maticí (tedy chození po "diagonále") FORD(kroku,celkem_surovin+1){ FORD(odecet[0],kroku+1){ if(odecet[0] > surovin[0]) break; FORD(odecet[1], kroku - odecet[0] +1){ if(odecet[1] > surovin[1]) break; FORD(odecet[2], kroku - odecet[0] - odecet[1]+1){ if(odecet[2] > surovin[2]) break; FORD(odecet[3],kroku - odecet[0] - odecet[1] - odecet[2]+1){ if(odecet[3] > surovin[3]) break; odecet[4] = kroku - odecet[0] - odecet[1] - odecet[2] - odecet[3]; if(odecet[4] <= surovin[4] && batoh[surovin[0] - odecet[0]] [surovin[1] - odecet[1]] [surovin[2] - odecet[2]] [surovin[3] - odecet[3]] [surovin[4] - odecet[4]]){ goto vypis; } } } } } } vypis: printf("%u\n",kroku); return 0; }