#include <stdio.h>#include <string.h>#include "math.h"#include <iostream>#define MAX(a, b) (a) > (b) ? (a) : (b)#define MIN(a, b) (a) < (b) ? (a) : (b)charbuf[4096],*ex=buf+4096,*ch=ex;usingnamespacestd;inlineboolread(){if(++ch>=ex){ch=buf;fread(buf,1,4096,stdin);}returntrue;}inlineintscan(intn=0){while(read()&&(*ch<'0'||*ch>'9'));do{n=n*10+*ch-'0';}while(read()&&*ch>='0'&&*ch<='9');returnn;}// 칸의 재료가 3개 이상이고, 최소 단위 이상의 재료를 가지고 있을 때 while문을 돌면서 재료를 사용하고 산출물의 개수를 1개씩 증가시키며, 남은 재료는 현재 칸에 임시로 저장해둔다voidDevide(inti,intM,intstack[][10],intR[],intQ[],inttop[]){M=stack[i][top[i]-1];if((M>=3)&&(M-R[i]>=0)){while((M>=3)&&(M-R[i]>=0)){M-=R[i];Q[i]++;}stack[i][top[i]-1]=M;}}// 누적 산출물이 최소인 재료를 찾는다voidMinimum(intQ[],intN,int*min,int*temp){(*min)=Q[0];for(intj=0;j<N;j++){if(Q[j]<=(*min)){(*min)=Q[j];(*temp)=j;}}}// 각 재료의 칸들을 오름차순으로 정리한다voidAcending(intN,inttop[],intstack[][10]){for(inti=0;i<N;i++){intmin,temp,index;for(intj=0;j<top[i]-1;j++){min=stack[i][j];for(intk=j;k<top[i]-1;k++){if(min>=stack[i][k]){min=stack[i][k];index=k;}}temp=stack[i][j];stack[i][j]=min;stack[i][index]=temp;}}}intmain(){#if defined(_DEBUG)freopen("data.txt","r",stdin);#endifintT;// 테스트 케이스cin>>T;for(inttestcase=0;testcase<T;testcase++){intN;// 재료 종류 수 (1<= N <= 10)intR[10]={0};// 재료 단위 (1<= R <= 1,000)intstack[10][10]={0};// 재료 칸 수 (1<= stack[][] <= 10)intusedBox=0;// 사용된 칸의 수inttop[10]={0};// 남은 칸의 수intQ[10]={0};// 몫(산출물)intM=0;// tempcin>>N;for(intg=0;g<N;g++){cin>>R[g]>>top[g];for(inth=0;h<top[g];h++)cin>>stack[g][h];}Acending(N,top,stack);inttemp=0;intmin=0;while(1){// 산출물 가장 적은 재료가 더 이상 재료칸을 가지고 있지 않거나, 사용된 재료칸이 10개가 된 경우 while문을 탈출한다 Minimum(Q,N,&min,&temp);if((top[temp]==0)||(usedBox==10))break;// 그렇지 않다면 산출물을 계산하고, 남은 재료는 다음 칸으로 이월시킨다else{Devide(temp,M,stack,R,Q,top);if(top[temp]!=1){stack[temp][top[temp]-2]+=stack[temp][top[temp]-1];}stack[temp][top[temp]-1]=0;top[temp]--;usedBox++;}}// 재료들의 산출물 값 중 최소가 생산품의 최대 개수가 된다printf("%d\n",min);}return0;}
ahn
9년 전