最基础的暴搜,连枝都没剪都能过,好水啊。。。
#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;
}