牛客oj 習題9.2神奇的口袋(DFS)&& poj2362 Square(DFS)

 

最基礎的暴搜,連枝都沒剪都能過,好水啊。。。

 

 

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <climits>
 
using namespace std;
 
const int MAXN = 25;
const int INF = INT_MAX;

int thing[MAXN], sum, n;
bool visit[MAXN];

void dfs(int weight, int current){
	if(weight == 40){
		sum ++;
		return;
	}
	for(int i = current; i < n; i++){
		if(visit[i] || (weight + thing[i] > 40)) continue;
		visit[i] = true;
		dfs(weight + thing[i], i + 1);
		visit[i] = false;
	}
	return;
}

int main(){
  //  freopen("in.txt", "r", stdin);
	while(~scanf("%d", &n)){
		for(int i = 0; i < n; i++){
			scanf("%d", &thing[i]);
		}
		memset(visit, false, sizeof(visit));
		sum = 0;
		dfs(0, 0);
		printf("%d\n", sum);
	}
	return 0;
}

 

 

 

王道上的原題,很經典,深搜判斷解是否存在。

基本思路是每次遍歷找出能構成正方形的邊。適當剪枝。

 

 

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <climits>
 
using namespace std;
 
const int MAXN = 25;
const int INF = INT_MAX;

int stick[MAXN], M, average;
bool visit[MAXN];

bool cmp(int x, int y){
	return x > y;
}

//每次在這堆棍子中找出一堆棍子使其組成正方形的邊 
//number爲已構成邊的個數,length爲當前拼接的木棍長度,current爲當前拼接的木棍序號 
bool dfs(int number, int length, int current){
	if(number == 3) return true;
	int sample = 0;
	for(int i = current; i < M; i++){
		if(visit[i] || (stick[i] == sample) || (length + stick[i] > average)) continue;
		visit[i] = true;
		if(length + stick[i] == average){//如果當前棍子可以構成正方形的邊 
			if(dfs(number + 1, 0, 0)){
				return true; 
			}
			else{
				sample = stick[i];//如果一根木棍無法拼接成功,那和他長度相同的木棍同樣無法拼接成功 
			}
		}
		else{//如果當前棍子不足以構成正方形的邊 
			if(dfs(number, length + stick[i], i + 1)){
				return true;
			}
			else{
				sample = stick[i];
			}
		}
		visit[i] = false;
	}
	return false;//找不到返回false 
}

int main(){
 //   freopen("in.txt", "r", stdin);
    int N;
	scanf("%d", &N);
	while(N--){
		scanf("%d", &M);
		int sum = 0;
		for(int i = 0; i < M; i++){
			scanf("%d", &stick[i]);
			sum += stick[i];
		}
		if(sum % 4 != 0){
			printf("no\n");
			continue;
		}
		average = sum / 4;
		sort(stick, stick+M, cmp);
		if(stick[0] > average){
			printf("no\n");
			continue;
		}
		memset(visit, false, sizeof(visit));
		if(dfs(0, 0, 0)) printf("yes\n");
		else printf("no\n");
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章