蒜头君手上有一些小木棍,它们长短不一,蒜头君想用这些木棍拼出一个等边三角形,并且每根木棍都要用到。 例如,蒜头君手上有长度为 1,2,3,3 的4根木棍,他可以让长度为1,2 的木棍组成一条边,另外 2 跟分别组成 2 条边,拼成一个边长为 3 的等边三角形。蒜头君希望你提前告诉他能不能拼出来,免得白费功夫。
输入格式
首先输入一个整数 n(3≤n≤20),表示木棍数量,接下来输入 n 根木棍的长度pi (1≤pi≤10000)。
输出格式
如果蒜头君能拼出等边三角形,输出”yes”,否则输出”no”。
样例输入
4
1 2 3 3
样例输出
yes
样例输入
4
1 1 1 1
样例输出
no
————————————————
这个代码我改了好几遍,最终
个人感觉有时候只是一点微小的改正,结果就可能不同!
重点在剪枝上,虽然并未改变时间复杂度,但是却大大缩短了时间
话不多说,上代码(为了剪枝可能代码比较多,未缩减)
#include<bits/stdc++.h>
using namespace std;
int a[25]={0};
int n=0,s=0;
bool isok=false;
void dfs(int x,int y,int z,int pos,int b)
{
if(pos>n||(x>b||y>b||z>b)) return;//这里是次重点;
if(pos==n&&(x==z)&&(z==y))
{
isok=true;
return ;
}
if(!isok){
dfs(x+a[pos],y,z,pos+1,b);
dfs(x,y+a[pos],z,pos+1,b);
dfs(x,y,z+a[pos],pos+1,b);
}//这里是重点!!,依靠这个大大缩短了时间复杂度(对于部分数据比较好用);
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
s=s+a[i];
}
if(s%3!=0)
{
printf("no");
return 0;
}
dfs(0,0,0,0,s/3);
if(isok==true)
printf("yes");
else
printf("no");
return 0;
}