牛客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;
}
发布了411 篇原创文章 · 获赞 72 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/Flynn_curry/article/details/104961296