P1120 54ptsTLE卡2周了(帮助必关)
  • 板块灌水区
  • 楼主xtr169
  • 当前回复7
  • 已保存回复7
  • 发布时间2024/11/24 20:22
  • 上次更新2024/11/24 21:33:09
查看原帖
P1120 54ptsTLE卡2周了(帮助必关)
186475
xtr169楼主2024/11/24 20:22

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;
}
2024/11/24 20:22
加载中...