반응형

첫 코드

DFS로 완전탐색을 했는데 시간이 초과되었다.

#include <bits/stdc++.h>
using namespace std;

int n, m, res=INT_MIN;
vector<pair<int, int> > v;

void DFS(int value, int weight){
	if(weight > m) return;
	else{
		res = max(res, value);
		for(int i=0; i<v.size();i++){
			DFS(value + v[i].second, weight+v[i].first);
		}
	}
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n >> m;
	for(int i=0; i<n; i++){
		int a, b;
		cin >> a >> b;
		v.push_back(make_pair(a,b));
	}
	
	DFS(0, 0);
	
	cout << res;
}

 

DP 이용

 

#include <bits/stdc++.h>
using namespace std;

int n, m, bag[1001], res;
vector<pair<int, int > > v;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m;
	for(int i=0; i<n; i++){
		int a, b;
		cin >> a >> b;
		v.push_back(make_pair(a,b));	
	}

	for(int i=0; i<v.size(); i++){
		for(int j=0; j<=m; j++){
			if(j-v[i].first>=0){
				bag[j] = max(bag[j-v[i].first] + v[i].second, bag[j]);
			}
		}
	}

	for(int i=0; i<=m; i++){
		res = max(res, bag[i]);
	}
	cout << res;

}

 

더 간단한 코드

 

#include <bits/stdc++.h>
using namespace std;

int n, m, bag[1001];

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> n >> m;
	for(int i=0; i<n; i++){
		int w, v;
		cin >> w >> v;

		for(int j=w; j<=m; j++){
			bag[j] = max(bag[j-w] + v, bag[j]);
		}
	}
	cout << bag[m];

}

냅색 알고리즘은

 

무게를 0부터 n까지 돌 때

 

각 요소마다 가방에 넣었을 때 최댓값이 된다면 갱신해주면 된다.

반응형
반응형
#include <bits/stdc++.h>
using namespace std;

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);

	int n;
	cin >> n;
	vector<int> arr(n+1), dy(n+1);
	
	dy[0]=1;
	dy[1]=1;
	
	for(int i=1; i<=n; i++){
		cin>> arr[i];
	}
	for(int i=2; i<=n; i++){
		int maxx = 0;
		for(int j=i-1; j>=1; j--){
			if(arr[j]<arr[i]){
				maxx = max(dy[j], maxx);
			}
		}
		dy[i] = maxx+1;
	}
	
	int ans=0;
	
	for(int i=1; i<=n;i++){
		ans = max(ans, dy[i]);
	}
	
	cout << ans;
	
	
	
}
반응형
반응형
#include <bits/stdc++.h>
using namespace std;

int dy[101];
int DFS(int n){
	if(dy[n]>0) return dy[n];
	if(n==1 || n==2) return n;
	else return dy[n]=DFS(n-1) + DFS(n-2);	
}

int main(){
//	freopen("input.txt","rt",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	int n;
	cin >> n;
	cout << DFS(n);
	return 0;
	
}
반응형

'Algorithm > etc' 카테고리의 다른 글

냅색 문제  (0) 2022.01.26
LIS 최대 부분 증가수열 - DP  (0) 2022.01.25
라이언 킹 심바 BFS 문제  (0) 2022.01.24
미로 최단거리 BFS 활용  (0) 2022.01.22
피자 배달 거리 문제 - DFS 활용 , 순열 조합 활용  (0) 2022.01.22
반응형
#include <bits/stdc++.h>
using namespace std;

int n, arr[30][30],ch[30][30],res;


int dx[4] = {-1,0,1,0};
int dy[4] = {0, -1,0, 1};


struct State{
	int x,y,dis;
	
	State(int a, int b, int c){
		x = a;
		y = b;
		dis = c;
	}
	bool operator<(const State &bb) const{
		if(dis==bb.dis){
			if(x==bb.x) return y>bb.y;
			else return x>bb.x;
		}
		else return dis>bb.dis;
	}
	
};

struct Lion{
	int x,y, size=2, eat=0;
	
	void sizeup(){
		size++;
		eat=0;
	}
};

int main(){
	//freopen("input.txt.txt","rt",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	Lion Simba;
	
	scanf("%d",&n);
	priority_queue<State> Q;
	for(int i=0; i<n; i++){
		for(int j=0; j<n;j++){
			int tmp;
			scanf("%d",&tmp);
			if(tmp==9){
				Simba.x = i;
				Simba.y = j;
			}
			else{
				arr[i][j] = tmp;
			}
		}
	}
	// 심바현재위치에서 갈수 있는 점들 탐색 
	// 갈수 있는 점들 우선순위 큐에 넣어준다.
	// 우선순위큐에서 우선순위 가장 높은 방문할 정점(지나갈 수 있는 것)을 뽑는다.
	// 그 정점이 먹을 수 있으면 먹고 , 심바 위치를 그 정점으로 바꿔준다. 
	// 큐는 먹이 정점을 모두다 방문 하면 끝난다.
	 
	
	
	Q.push(State(Simba.x, Simba.y, 0));
	while(!Q.empty()){
		int cur_x = Q.top().x;
		int cur_y = Q.top().y;
		int cur_dis = Q.top().dis;
		Q.pop();
		if(arr[cur_x][cur_y]!=0 && arr[cur_x][cur_y]<Simba.size){
			Simba.x=cur_x;
			Simba.y=cur_y;
			Simba.eat++;
			if(Simba.eat >= Simba.size) Simba.sizeup();
			arr[cur_x][cur_y] = 0;
			for(int i=0; i<n; i++){
				for(int j=0; j<n; j++){
					ch[i][j]=0;
				}
			}
			while(!Q.empty()) Q.pop();
			res = cur_dis;
		}
		
		for(int i=0; i<4; i++){
			int nx = cur_x+dx[i];
			int ny = cur_y+dy[i];
			
			if(nx<0||nx>=n||ny<0||ny>=n||ch[nx][ny]>0) continue;
			if(arr[nx][ny] > Simba.size) continue;
			ch[nx][ny] = 1;
			Q.push(State(nx,ny,cur_dis+1));
				
		}	
		
	}
	
	printf("%d",res);
	

}
반응형
반응형
#include <bits/stdc++.h>
using namespace std;

struct Node{
	int row, col;
	Node(int a, int b){
		row=a;
		col=b;
	}
	
};

int arr[7][7];
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};

int main(){
	//freopen("input.txt.txt","rt",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	queue<Node> Q;

	for(int i=0; i<7; i++){
		for(int j=0; j<7; j++){
			scanf("%d",&arr[i][j]);
			if(arr[i][j]==1) arr[i][j] = -1;
		}
	}
	arr[0][0] = 1;
	Q.push(Node(0,0));
	while(!Q.empty()){
		int x = Q.front().row;
		int y = Q.front().col;
		Q.pop();
		
		if(x==6 && y==6) break;
		
		
		for(int i=0; i<4; i++){
			int nx = x+dx[i];
			int ny = y+dy[i];
			
			if(nx<0||nx>6||ny<0||ny>6) continue;
			if(arr[nx][ny]==-1 || arr[nx][ny]>0) continue;
			
			arr[nx][ny] = arr[x][y]+1;
			Q.push(Node(nx,ny));
		}
	}
	
	printf("%d",arr[6][6]-1);
}

장애물을 -1로 두고

 

거리를 양수로 표기하면서 BFS를 돌면 편하다.

 

첫 시작점도 방문했다는걸 표기하기 위해 1로 둔다.

 

나중에 답을 구할 땐 1을 다시 빼준다.

반응형
반응형

첫 코드

#include <bits/stdc++.h>
using namespace std;

int n,m, arr[51][51], ch[20], minn=INT_MAX;
vector<pair<int,int> > v;

void DFS(int node){
	if(node==m){
		int cnt=0;
		//도시 피자배달 거리 구하기  
		//ch[i]==1 이면 선택된 피잣집 
		
		for(int i=1; i<=n; i++){
			for(int j=1; j<=n; j++){
				int min_dist=INT_MAX;
				if(arr[i][j]==1){
					for(int k=0; k<v.size(); k++){
						if(ch[k]==1){
							int cur_dist = abs(i-v[k].first)+abs(j-v[k].second);
							if(min_dist>cur_dist){
								min_dist = cur_dist;
							}
							
						}
						else continue;
					}
					cnt += min_dist;
				}
			}
			
		} 
		if(cnt<minn) minn=cnt;
		
	}
	else{
		for(int i=0; i<v.size(); i++){
			if(ch[i]==0){
				ch[i]=1;
				DFS(node+1);
				ch[i]=0;
			}
		}	
		
	}
	
}

int main(){
	//freopen("input.txt.txt","rt",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);

	// 피잣집 선택 갯수 
	// 6개중 4개 선택 ---> 거리 최솟값 
	
	int i,j;
	// 피잣집 벡터 
	
	
	scanf("%d %d",&n, &m);
	
	
	for(i=1; i<=n; i++){
		for(j=1; j<=n; j++){
			scanf("%d",&arr[i][j]);
			
			if(arr[i][j]==2) {
				v.push_back(make_pair(i, j));
			}
		}
	}
	// 피잣집 선택  
	DFS(0);
	
	printf("%d",minn);
	
}

문제점

 

1. 피잣집을 구할 때 순열로 뽑았다. DFS에서 경우의수가 불필요하게 많이 계산된다.

 

2. 필요한 정보는 집과 피자집의 좌표인데 그 외의 불필요한 좌표를 모두 돌면서 시간이 오래걸린다.

 

 

1차 수정

#include <bits/stdc++.h>
using namespace std;

int n, m, ch[20], minn=INT_MAX;
vector<pair<int, int> > hs;
vector<pair<int, int> > pz;

void DFS(int s, int L){
	if(L==m){
		int cnt = 0;
		for(int i=0; i<hs.size(); i++){
			int hs_min =INT_MAX;
			for(int j=0; j<pz.size(); j++){
				if(ch[j]==0) continue;
				int hs_dist = abs(hs[i].first-pz[j].first) + abs(hs[i].second - pz[j].second);
				if(hs_min> hs_dist) hs_min = hs_dist;
			}
			cnt += hs_min;	
		}
		if(minn>cnt) 
		{
			minn=cnt;

		}
	}
	else{
		//피자집 순열 구함  
		for(int i=s; i<pz.size(); i++){
			ch[i] = 1;
			DFS(i+1, L+1);
			ch[i] = 0;
		}
	}
}


int main(){
	//freopen("input.txt.txt","rt",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	int i, j,tmp;
	
	scanf("%d %d",&n,&m);
	
	for(i=0; i<n; i++){
		for(j=0; j<n; j++){
			scanf("%d", &tmp);
			if(tmp==1){
				hs.push_back(make_pair(i,j));
			}
			else if(tmp==2){
				pz.push_back(make_pair(i,j));
			}
		}	
	}
	
	DFS(0,0);
	printf("%d",minn);
	
	
}

ch배열에 해당하는 피잣집 인덱스를 직접 넣는게 아니라

피잣집 인덱스가 해당하면 표시해주는 방법으로 했다.

 

ch[0] = 1 이면 0번 피잣집이 조합에 포함되고, ch[1] = 0 이면 1번 피잣집은 조합에 포함되지 않는 걸로 지정했다.

이렇게하면 반드시 체크를 해제해주는 과정이 필요하다.

 

ch배열에 해당 피잣집 인덱스를 직접 넣어주면 더 간단하게 풀 수 있다.

예를들어 ch[0] = 1 ch[1] = 2 ch[2] = 3 이렇게하면 1번, 2번, 3번 피잣집이 해당한다.

 

 

#include <bits/stdc++.h>
using namespace std;

int n, m, ch[20], minn=INT_MAX;
vector<pair<int, int> > hs;
vector<pair<int, int> > pz;

void DFS(int s, int L){
	if(L==m){
		int cnt = 0;
		for(int i=0; i<hs.size();i++){
			int hs_min = INT_MAX;
			for(int j=0; j<m; j++){
				int dist =abs(pz[ch[j]].first - hs[i].first) + abs(pz[ch[j]].second - hs[i].second);
				if(hs_min > dist) hs_min = dist;
			}
			cnt+=hs_min;
		}
		if(minn>cnt) minn = cnt;
	}
	else{
		//피자집 순열 조합  구함  
		for(int i=s; i<pz.size(); i++){
			ch[L] = i;
			DFS(i+1, L+1);
		}
	}
}


int main(){
	//freopen("input.txt.txt","rt",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	int i, j,tmp;
	
	scanf("%d %d",&n,&m);
	
	for(i=0; i<n; i++){
		for(j=0; j<n; j++){
			scanf("%d", &tmp);
			if(tmp==1){
				hs.push_back(make_pair(i,j));
			}
			else if(tmp==2){
				pz.push_back(make_pair(i,j));
			}
		}	
	}
	
	DFS(0,0);
	printf("%d",minn);
	
	
}

ch 배열에 직접 해당 피잣집의 인덱스를 넣어주니 코드가 더 간결해졌다.

 

 

 

순열 조합 문제

https://dingcoding.tistory.com/entry/%EB%B0%B1%EC%A4%80-15650%EB%B2%88-N%EA%B3%BC-M-2-%EC%88%9C%EC%97%B4%EC%9D%98-%EC%A1%B0%ED%95%A9-%EB%AC%B8%EC%A0%9C-DFS%EB%A1%9C-%ED%92%80%EA%B8%B0

 

 

 

반응형

'Algorithm > etc' 카테고리의 다른 글

라이언 킹 심바 BFS 문제  (0) 2022.01.24
미로 최단거리 BFS 활용  (0) 2022.01.22
순열 구하기 - DFS  (0) 2022.01.20
벨만-포드 알고리즘  (0) 2022.01.20
다익스트라 알고리즘  (0) 2022.01.20
반응형
#include <bits/stdc++.h>
using namespace std;

int n,r,ch[20],path[20],cnt;
vector<int> v;

//----


void DFS(int L){
	if(L==r){
		for(int i=0; i<L;i++){
			printf("%d ",path[i]);
		
		}
		cnt++;
		printf("\n");
	
	}
	else{
		
		
		for(int i=0; i<v.size(); i++){
			if(ch[v[i]]==0){
				path[L]= v[i];	
				ch[v[i]] = 1;
				DFS(L+1);
				
				ch[v[i]] = 0;
			}
		}
		
		
	}
	
	
}

int main(){
	//freopen("input.txt.txt","rt",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	int tmp;
	
	scanf("%d %d",&n,&r);
	for(int i=0; i<n; i++){
		scanf("%d", &tmp);
		v.push_back(tmp);
	}
	DFS(0);
	printf("%d",cnt);
}

DFS를 활용해 순열을 구할 수 있다.

반응형

'Algorithm > etc' 카테고리의 다른 글

미로 최단거리 BFS 활용  (0) 2022.01.22
피자 배달 거리 문제 - DFS 활용 , 순열 조합 활용  (0) 2022.01.22
벨만-포드 알고리즘  (0) 2022.01.20
다익스트라 알고리즘  (0) 2022.01.20
Prim MST  (0) 2022.01.19
반응형

간선의 갯수를 1부터 n-1까지 탐색하면서

 

최적의 경로를 찾는다.

 

다익스트라 알고리즘과 달리 간선의 값이 음수여도 사용이 가능하다.

#include <bits/stdc++.h>
using namespace std;

int dist[101];
struct Edge{
	int s;
	int e;
	int val;
	Edge(int a, int b, int c){
		s=a;
		e=b;
		val=c;
	}
};

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int i,n,m,a,b,c,j,s,e;
	vector<Edge> Ed;
	scanf("%d %d", &n, &m);
	
	for(i=1; i<=m; i++){
		scanf("%d %d %d",&a,&b,&c);
		Ed.push_back(Edge(a,b,c));
	}
	for(i=1; i<=n; i++){
		dist[i]=INT_MAX;
	}
	scanf("%d %d",&s,&e);
	dist[s]=0;
	for(i=1; i<n; i++){
		for(j=0; j<Ed.size(); j++){
			int s=Ed[j].s;
			int e=Ed[j].e;
			int w=Ed[j].val;
			if(dist[s]!=INT_MAX && dist[s]+w<dist[e]){
				dist[e]=dist[s]+w;
			}
		}

	}
	for(j=0; j<Ed.size();j++){
		int u=Ed[j].s;
		int v=Ed[j].e;
		int w=Ed[j].val;
		if(dist[u]!=INT_MAX && dist[u]+w<dist[v]){
			printf("-1\n");
			return 0;
		}
		
	}
	
	printf("%d\n", dist[e]);
	return 0;

}
반응형

'Algorithm > etc' 카테고리의 다른 글

피자 배달 거리 문제 - DFS 활용 , 순열 조합 활용  (0) 2022.01.22
순열 구하기 - DFS  (0) 2022.01.20
다익스트라 알고리즘  (0) 2022.01.20
Prim MST  (0) 2022.01.19
크루스칼 알고리즘 Kruskal MST(최소스패닝트리)  (0) 2022.01.18

+ Recent posts