티스토리 뷰
https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5V1SYKAaUDFAWu
재귀를 이용하여 각 행에 대하여 -1(약품 안씀), 0(약품 A 사용), 1(약품 B 사용)의 모든 경우를 만들어서 합격기준을 만족하는지 확인한다. 경우의 수를 만드는 도중 약품 투입 횟수가 현재 답과 같거나 크다면 종료하고 가지치기한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #include <cstdio> #include <string> #include <algorithm> using namespace std; int t,d,w,k,ans,f[13][20],tf[13][20],s[13]; bool pass() { for(int j=0;j<w;j++) { bool f1=false; for(int i=0;i<=d-k;i++) { bool f2=true; for(int p=i+1;p<i+k;p++) if(tf[i][j]!=tf[p][j]) f2=false; if(f2) { f1=true; break; } } if(f1) continue; else return false; } return true; } void go(int n,int c) // 길이,약품투입횟수 { if(c>=ans) return; if(n==d+1) { for(int i=0;i<d;i++) for(int j=0;j<w;j++) tf[i][j]=f[i][j]; for(int i=0;i<d;i++) if(s[i]!=-1) for(int j=0;j<w;j++) tf[i][j]=s[i]; if(pass()) ans=min(ans,c); return; } s[n]=-1,go(n+1,c); if(n==d) return; s[n]=0,go(n+1,c+1); s[n]=1,go(n+1,c+1); } int main() { scanf("%d",&t); for(int T=1;T<=t;T++) { scanf("%d %d %d",&d,&w,&k); for(int i=0;i<d;i++) for(int j=0;j<w;j++) scanf("%d",&f[i][j]); ans=15; go(0,0); printf("#%d %d\n",T,ans); } return 0; } | cs |
'Algorithm > SW Expert Academy' 카테고리의 다른 글
2117 홈 방범 서비스 (0) | 2018.03.24 |
---|---|
2115 벌꿀채취 (0) | 2018.03.24 |
2105 디저트 카페 (2) | 2018.03.17 |
1953 탈주범 검거 (0) | 2018.03.16 |
1952 수영장 (0) | 2018.03.14 |