P1120小木棍,如题,不知道为什么能剪枝的都剪了还只有54pts,求大佬帮助(关注)
//pie木棍数 len存储输入 sum木棍长度 vis标记访问 nextt优化,预处理出了排序后每根木棍后面的最后一根与这根木棍长度相等的木棍
#include <bits/stdc++.h>
#define fir first
#define sec second
#define ll long long
#define pb push_back
#define mp make_pair
using namespace std;
int n,len[100],pie,tmp,sum,vis[100],nmax,nextt[100];
bool flag;
inline int read()
{
int x=0,f=1;
char tmp;
tmp=getchar();
if(tmp<'0'||tmp>'9')
{
if(tmp=='-')
f=-1;
}
else
{
x=tmp-'0';
}
tmp=getchar();
while(tmp>='0'&&tmp<='9')
{
x*=10;
x+=tmp-'0';
tmp=getchar();
}
return f*x;
}
inline int dfs(int now,int last,int nlen,int lenth)
{
if(nlen==lenth)
if(now==sum/lenth)
return 1;
else
return dfs(now+1,0,0,lenth);
int l=last,r=pie,mid;
while(l<r)
{
mid=(l+r)>>1;
if(len[mid]<=lenth-nlen) r=mid;
else l=mid+1;
}
for(int i=l;i<pie;i++)
{
if(!vis[i])
{
vis[i]=1;
if(dfs(now,i,nlen+len[i],lenth))
return 1;
vis[i]=0;
i=nextt[i];
if(i==pie) return 0;
if(lenth-nlen==len[i]||nlen+nlen==lenth) return 0;
}
}
return 0;
}
//now 目前正在拼第几根 last由哪一个转移来的 nlen当前木棍长度 lenth目标长度
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
n=read();
for(int i=0;i<n;i++)
{
tmp=read();
if(tmp>50) continue;
len[pie++]=tmp,sum+=tmp;
nmax=max(nmax,tmp);
}
sort(len,len+pie,cmp);
nextt[pie]=pie;
for(int i=pie-1;i>0;i--)
{
if(len[i]==len[i+1]) nextt[i]=nextt[i+1];
else nextt[i]=i;
}
for(int i=nmax;i<=(sum>>1)+1;i++)
{
if(sum%i!=0) continue;
if(dfs(1,-1,0,i))
{
flag=1;
printf("%d",i);
break;
}
}
if(flag==0) printf("%d",sum);
return 0;
}