P1120 小木棍


因为开学好长时间没有做题,也是把自己写了好久的题补上

从看题解写到将自己的代码改对真的累

主要的优化就是nxt,二分,sort三个,以及及时的退出


#include <bits/stdc++.h>
using namespace std;
int num[70],n,a,flg[70],sum,tag,ma,cnt,nxt[70];
int cmp(int a,int b){return a>b;}
void dfs(int now, int tnt,int last) {
    if(tag)return;
       int l=last,r=n,ans;
    while(l<=r){
        int mid=(l+r)>>1;
        if(num[mid]<=now) {r=mid-1;ans=mid;    }
        else l=mid+1;
    }
    for (int i =ans;i<=n;i++)
        if (!flg[i]) {
            if (num[i]<now) {
                flg[i]=1;cnt++;
                dfs(now-num[i],tnt,i+1);
                flg[i]=0;cnt--;
                if(now==num[i]||now==tnt)return;i=nxt[i];
            }
            if (num[i]==now) {
                flg[i]=1;cnt++;
                if (cnt==n)tag=1;
                else dfs(tnt, tnt,1);
                flg[i]=0;cnt--;
                return;
            }    
        }
}
int main() {
    cin>>n;
    int tot=0;
    for (int i=1;i<=n;i++) {
        cin>>a;
        if(a<=50){num[++tot]=a;sum+=a;}
    }
    n=tot;
    sort(num+1,num+1+n,cmp);
    nxt[n]=n;
    for(int i=n-1;i>0;i--){
        if(num[i]==num[i+1])nxt[i]=nxt[i+1];
        else nxt[i]=i;
    }
    for (int i=num[1];i<=sum/2;i++)
        if (sum%i==0) {
            tag=0;cnt=0;
            memset(flg, 0, sizeof(flg));
            dfs(i,i,1);
            if(tag){cout<<i;return 0;}
        }
        cout<<sum;
}
原文地址:https://www.cnblogs.com/SFWR-YOU/p/11502495.html