对着第一篇题解调了一下午也没搞定
本蒟蒻自觉已经把题解中的剪枝全加上了
#include<cstdio>
#include<algorithm>
#include <cstdlib>
#include<iostream>
#include<cstring>
#include<cmath>
#include<ratio>
#include<shared_mutex>
#include<utility>
#include<vector>
#include<queue>
#include<bitset>
#include<iostream>
#include<queue>
#include<stack>
#include<ctime>
#include<list>
using namespace std;
#define lowbit(x) x&(-x)
int n;
int Lenth[70],tot;
int sum,MMn;
bool CMP(int a,int b) {return a>b;}
bool isUse[70];
int N;
int bound(int val)
{
int l=1,r=tot;
int mid;
while (l<r)
{
mid=(l+r)/2;
if (Lenth[mid]>val) l=mid+1;
else r=mid;
}
return l;
}
int tree[70];
inline void update_point(int pos,int date)
{
while(pos<=n)
{
tree[pos]+=date;
pos+=lowbit(pos);
}
}
inline int query_sum(int x)
{
int res=0;
while(x)
{
res+=tree[x];
x-=lowbit(x);
}
return res;
}
int Next[70];
bool dfs(int target/*目标长度*/,int restR/*当前在拼的木棍距离目标剩余长度*/,
int restStick/*剩的棍子*/,int sumSuccess/*已经拼成的*/,
int last/*上次拼的长度*/,int lastpos/*上一根的位置*/)
{
if (sumSuccess==N) return true;
for (int i=max(bound(restR),lastpos?lastpos:bound(last));i<=tot;i++)
{
if (isUse[i]) continue;
if (restR==Lenth[i])
{
isUse[i]=1;
if (dfs(target,target,restStick-1,sumSuccess+1,target,0))
return true;
isUse[i]=0;
return false;
}
if (query_sum(tot)-query_sum(i-1)<restR) return false;
update_point(i,-Lenth[i]);
isUse[i]=1;
if (dfs(target,restR-Lenth[i],restStick-1,sumSuccess,Lenth[i],i+1))
return true;
isUse[i]=0;
update_point(i,Lenth[i]);
if (restR==target) return false;
i=Next[i];
}
return false;
}
int main()
{
scanf("%d",&n);
for (int i=1,x;i<=n;i++)
{
scanf("%d",&x);
if (x>50) continue;
Lenth[++tot]=x;
sum+=x;
MMn=max(MMn,x);
}
sort(Lenth+1,Lenth+1+tot,CMP);
for (int i=tot;i>=1;i--)
update_point(i,Lenth[i]);
Next[tot]=tot;
for (int i=tot-1;i>=1;i--)
if (Lenth[i]==Lenth[i+1]) Next[i]=Next[i+1];
else Next[i]=i;
for (int i=MMn;i<=sum;i++)
{
if (sum%i) continue;
N=sum/i;
if (dfs(i,i,tot,0,i,0))
{
printf("%d",i);
return 0;
}
}
return 0;
}
···