这道题和HDOJ的square深搜差不多,同样属于深搜中减枝比较经典的题目。
递归最重要的是找到“死胡同”和“岔路口”。这里的死胡同是当前长度等于正方形的边长,岔路口是:选或者不选当前的木棍。
为了更好减枝,我们先把木棍长度排下序。注意:dfs中,最好设置为函数变量而不是全局变量,猜测是因为每次递归都要返回上次的状态,所以要用全局变量的时候我们在回归上次状态的时候把该变量也恢复过来。为了简单最好用全局变量
代码如下:(边数为函数变量时)
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const long long maxn = 35;
int st[maxn];
int vis[maxn];
int num[11000];
bool flag = false;
int avg,n;
void dfs(int len,int pos,int cnt)
{
if(len > avg)
return;
if(len == avg)
{
cnt++;
if(cnt == 3)
{
flag = true;
return;
}
len = 0;
pos = 0;
//cout<<"cnt="<<cnt<<endl;
}
if(flag)
return;
for(int i=pos; i<n; i++)
{
if(flag)
return;
if(len+st[i] > avg && vis[i] == 0)
return;
if(len+st[i] <= avg && vis[i] == 0)
{
vis[i] = 1;
//cout<<"len+st[i]="<<len+st[i]<<endl;
//cout<<"pos="<<pos<<endl;
dfs(len+st[i],i,cnt);
vis[i] = 0;
}
}
}
int main()
{
for(int i=0; i<11000; i++)
{
num[i] = 0;
}
int sum = 0;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>st[i];
sum+=st[i];
vis[i] = 0;
}
if(sum%4 !=0)
{
cout<<"No"<<endl;
return 0;
}
avg = sum/4;
sort(st,st+n);
for(int i=0; i<n; i++)
{
num[st[i]]++;
if(st[i] > avg)
{
cout<<"No"<<endl;
return 0;
}
}
dfs(0,0,0);
if(flag)
{
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
return 0;
}
当边数为全局变量时:
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const long long maxn = 35;
int st[maxn];
int vis[maxn];
int num[11000];
bool flag = false;
int cnt=0,avg,n;
void dfs(int len,int pos)
{
if(len > avg)
return;
if(len == avg)
{
cnt++;
if(cnt == 3)
{
flag = true;
return;
}
len = 0;
pos = 0;
//cout<<"cnt="<<cnt<<endl;
}
if(flag)
return;
for(int i=pos; i<n; i++)
{
if(flag)
return;
if(len+st[i] > avg && vis[i] == 0)
return;
if(len+st[i] <= avg && vis[i] == 0)
{
vis[i] = 1;
//cout<<"len+st[i]="<<len+st[i]<<endl;
//cout<<"pos="<<pos<<endl;
dfs(len+st[i],i);
if(len + st[i] == avg)
cnt--;
vis[i] = 0;
}
}
}
int main()
{
for(int i=0; i<11000; i++)
{
num[i] = 0;
}
int sum = 0;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>st[i];
sum+=st[i];
vis[i] = 0;
}
if(sum%4 !=0)
{
cout<<"No"<<endl;
return 0;
}
avg = sum/4;
sort(st,st+n);
for(int i=0; i<n; i++)
{
num[st[i]]++;
if(st[i] > avg)
{
cout<<"No"<<endl;
return 0;
}
}
dfs(0,0);
if(flag)
{
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
return 0;
}