0x22 深度优先搜索0x23剪枝0x24迭代加深meet-in-the-middle

一、普通

AcWing 165. 小猫爬山

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,c[20],ans=1e9,car[20],cnt,w;
void dfs(int x){
    if(x==n+1){
        ans=min(ans,cnt);
        return ;
    }
    if(ans<=cnt)return ;
    car[++cnt]=c[x];dfs(x+1);
    cnt--;
    for(int i=1;i<=cnt;i++){
        if(car[i]+c[x]<=w){
            car[i]+=c[x];
            dfs(x+1);
            car[i]-=c[x];
        }
    }
}
int main(){
    scanf("%d%d",&n,&w);
    for(int i=1;i<=n;i++){
        scanf("%d",&c[i]);
    }
    sort(c+1,c+n+1,greater<int>());
    dfs(1);
    printf("%d",ans);
	return 0;
}

AcWing 166. 数独

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int r[10],c[10],g[10],mp[10][10],fd;
char s[90];

inline int P(int i,int j){
    return (i/3)*3+(j/3);
}
void dfs(){
    if(fd==1)return;
    int f=1;int x=0,y=0,p=0,l=0,o;
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            if(mp[i][j]==-1){
                f=0;
                 o=r[i]|c[j]|g[P(i,j)];
                if(o==(1<<9)-1){
                    return;
                }
                else{
                    if(__builtin_popcount(o)>p){
                        p=__builtin_popcount(o);
                        l=(o);
                        x=i,y=j;
                    }
                }
            }
        }
    }
    if(f){
        fd=1;
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                printf("%d",mp[i][j]+1);
            } 
        }
        printf("\n");
        return;
    }
    int u=r[x],v=c[y],w=g[P(x,y)];
    for(register int i=0;i<9;i++){
        if(!((l>>i)&1)){
            r[x]|=(1<<i);
            c[y]|=(1<<i);
            g[P(x,y)]|=(1<<i);
            mp[x][y]=i;
            dfs();
            mp[x][y]=-1;
            r[x]=u;
            c[y]=v;
            g[P(x,y)]=w;
        }
    }
}
int main(){
    while(scanf("%s",s)){
        fd=0;
        if(s[0]=='e')break;
        for(int i=0;i<9;i++){
            r[i]=c[i]=g[i]=0;
        }
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                if(s[i*9+j]=='.'){mp[i][j]=-1;}
                else{
                    mp[i][j]=s[i*9+j]-'1';
                    r[i]|=(1<<mp[i][j]);
                    c[j]|=(1<<mp[i][j]);
                    g[P(i,j)]|=(1<<mp[i][j]);
                }
            }
        }
        dfs();
    }
	return 0;
}

AcWing 167. 木棒

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,a[70],sum,len,cnt,v[70];
int dfs(int x,int l,int la){
    if(l==len){
        return dfs(x+1,0,1);
    }
    if(x==cnt+1){
        return 1;
    } 
    int lf=-1,res;
    for(int i=la;i<=n;i++){
        if(v[i]==0&&a[i]!=lf&&a[i]+l<=len){
            v[i]=1;
            res=dfs(x,l+a[i],i+1);
            v[i]=0;
            if(res){
                return 1;
            }
            lf=a[i];
            if(l==0||l+a[i]==len)return 0;
        }
    }
    return 0;
}
int main(){
    while(~scanf("%d",&n)&&n){
        sum=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            sum+=a[i];
        }
        sort(a+1,a+n+1,greater<int>());
        for(len=1;len<=sum;len++){
            if(sum%len)continue;
            cnt=sum/len;
            if(dfs(1,0,1)){
                printf("%d\n",len);
                break;
            }
        }
    } 
	return 0;
}

AcWing 168. 生日蛋糕

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,m,r[25],h[25],ans=1e9,ms[25],mv[25];

void dfs(int dep,int v,int s){
    if(dep==0){
        if(v==n)ans=min(ans,s);
        return ;
    }
    if(s+ms[dep-1]>ans||v+mv[dep-1]>n||s+2*(n-v)/r[dep+1]>ans)return ;
    for(int R=min(r[dep+1]-1,(int)sqrt(n-v));R>=dep  ;R--){
        for(int H=min(h[dep+1]-1,(n-v)/R/R);H>=dep;H--){
            
            h[dep]=H;r[dep]=R;
            if(dep==m)dfs(dep-1,v+R*R*H,s+2*R*H+R*R);
            else dfs(dep-1,v+R*R*H,s+2*R*H);
        }
    }
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=20;i++){
        ms[i]=ms[i-1]+2*i*i;
        mv[i]=mv[i-1]+i*i*i;
    }
    h[m+1]=1e9;r[m+1]=1e9;
    dfs(m,0,0);
    if(ans!=1e9)printf("%d",ans);
    else printf("0");
	return 0;
}

AcWing 169. 数独2

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#pragma GCC optimize(2)

string S[20];
int fd=0;
int mp[17][17],id[17][17],s[17][17];
int r[17],c[17],g[17],jl[30000][17][17],tot,lr[30000][17],lc[30000][17],lg[30000][17],lmp[30000][17][17];
pair<int,int>ad[17]={{0,0},{0,4},{0,8},{0,12},
                     {4,0},{4,4},{4,8},{4,12},
                     {8,0},{8,4},{8,8},{8,12},
                     {12,0},{12,4},{12,8},{12,12}};
unordered_map<int,int>p;
inline bool jq(int a,int b){
    return (a>>b)&1;
}
inline int lowbit(int x){
    return x&(-x);
}
inline void draw(int i,int j,int x){
    mp[i][j]=x;
    r[i]|=(1<<x);
    c[j]|=(1<<x);
    g[id[i][j]]|=(1<<x);
    for(register int d=0;d<16;d++){
        s[i][d]|=(1<<x);
        s[d][j]|=(1<<x);
    }
    for(register int u=ad[id[i][j]].first;u<ad[id[i][j]].first+4;u++)
        for(register int v=ad[id[i][j]].second;v<ad[id[i][j]].second+4;v++)
            s[u][v]|=(1<<x);
}
inline void re(int now){
    for(register int i=0;i<16;i++)r[i]=lr[now][i],c[i]=lc[now][i],g[i]=lg[now][i];
    for(register int i=0;i<16;i++)for(register int j=0;j<16;j++)s[i][j]=jl[now][i][j],mp[i][j]=lmp[now][i][j];
}
inline void init(){
    for(register int i=0;i<16;i++){
        for(register int j=0;j<16;j++){
            s[i][j]=(r[i]|c[j]|g[id[i][j]]);
        }
    }
}
void print(){
    for(register int i=0;i<16;i++){
        for(register int j=0;j<16;j++){
            if(mp[i][j]==-1)printf("-");
            else printf("%c",mp[i][j]+'A');
        }
        printf("\n");
    }
    printf("\n");
}
void prints(){
    for(int i=0;i<16;i++){
        for(int j=0;j<16;j++){
             printf("%d ",s[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}
void printr(){
    for(int i=0;i<16;i++){
        printf("%d ",r[i]);
    }
    puts("");
}
void dfs(){
    //cout<<tot<<endl;
    if(fd)return;
    {//jz1
    
        for(register int i=0;i<16;i++)for(register int j=0;j<16;j++)if(mp[i][j]==-1){
            if(s[i][j]==(1<<16)-1){
                return;
            }
            if(__builtin_popcount(s[i][j])==15){
                draw(i,j,p[lowbit(~s[i][j])]);
                dfs();return ;
            }
        }
    }
    {//z2
        int x,y,f=2;
        for(register int i=0;i<16;i++){
            for(register int ch=0;ch<16;ch++){
                if(jq(r[i],ch))continue;
                f=0;
                for(int j=0;j<16;j++){
                    if(mp[i][j]!=-1)continue;;
                    if(!jq(s[i][j],ch)){
                        
                        f++;
                        x=i,y=j;
                    }
                }
                if(f==0){
                    return;
                }
                if(f==1){
                    draw(x,y,ch);dfs();
                    return ;
                }
            }
        }
    }
    {//zj3
        int x,y,f=2;
        for(register int j=0;j<16;j++){
            for(register int ch=0;ch<16;ch++){
                if(jq(c[j],ch))continue;
                f=0;
                for(int i=0;i<16;i++){
                    if(mp[i][j]!=-1)continue;;
                    if(!jq(s[i][j],ch)){
                        
                        f++;
                        x=i,y=j;
                    }
                }
                if(f==0){
                    return;
                }
                if(f==1){
                    draw(x,y,ch);dfs();return;
                }
            }
        }
    }
    {//zj4
        int x,y,f=2;
        for(register int k=0;k<16;k++){
            for(register int ch=0;ch<16;ch++){
                if(jq(g[k],ch))continue;
                f=0;
                for(int i=ad[k].first;i<ad[k].first+4;i++){
                    for(int j=ad[k].second;j<ad[k].second+4;j++){
                        if(mp[i][j]!=-1)continue;;
                        if(!jq(s[i][j],ch)){
                            f++;
                            x=i,y=j;
                        }
                    }
                }
                if(f==0)return;
                if(f==1){
                    draw(x,y,ch);dfs();
                    return ;
                }
            }
        }
    }
    {//bj
        
        int flag=1;
        for(register int i=0;i<16;i++){
            for(register int j=0;j<16;j++){
                if(mp[i][j]==-1){
                   flag=0;
                }
            }
        }
        if(flag){
            fd=1;
            print();
            return ;
        }
    }
    

    {//zy
        int x,y,ma=0,now=++tot;
        for(register int i=0;i<16;i++)for(register int j=0;j<16;j++)jl[now][i][j]=s[i][j],lmp[now][i][j]=mp[i][j];
        for(register int i=0;i<16;i++)lr[now][i]=r[i],lc[now][i]=c[i],lg[now][i]=g[i];
        for(register int i=0;i<16;i++)for(register int j=0;j<16;j++)if(mp[i][j]==-1){
            if(__builtin_popcount(s[i][j])>ma){
                ma=__builtin_popcount(s[i][j]);
                x=i,y=j;
            }
        }
        for(register int ch=0;ch<16;ch++){
            
            if(!jq(s[x][y],ch)){
                draw(x,y,ch);
                dfs();
                re(now);
            }
        }
    }
}
int main(){
    for(int i=0;i<=16;i++){
        p[1<<i]=i;
    }
    while(cin>>S[0]){
        tot=0;
        memset(r,0,sizeof(r));
        memset(c,0,sizeof(c));
        memset(g,0,sizeof(g));
        memset(mp,0,sizeof(mp));
        memset(s,0,sizeof(s));
        fd=0;
        for(int i=1;i<16;i++){
            cin>>S[i];
        }
        for(int i=0;i<16;i++){
            for(int j=0;j<16;j++){
                
                id[i][j]=(i/4)*4+j/4;                                   
                if(S[i][j]=='-')mp[i][j]=-1;
                else mp[i][j]=S[i][j]-'A',r[i]|=(1<<mp[i][j]),c[j]|=(1<<mp[i][j]),g[id[i][j]]|=(1<<mp[i][j]);
            }
        }
        init(); 
        dfs();
        //printf("%d",fd);
    }
	return 0;
}

AcWing 183. 靶形数独

同9*9数独,剪枝是

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define pr  for(int i=0;i<9;i++){for(int j=0;j<9;j++)printf("%d ",mp[i][j]+1);puts("");}puts("");
int mp[9][9],ans,id[9][9],r[9],c[9],g[9],cs;
int sc[9][9]={{6,6,6,6,6,6,6,6,6},{6,7,7,7,7,7,7,7,6},{6,7,8,8,8,8,8,7,6},{6,7,8,9,9,9,8,7,6},{6,7,8,9,10,9,8,7,6},{6,7,8,9,9,9,8,7,6},{6,7,8,8,8,8,8,7,6},{6,7,7,7,7,7,7,7,6},{6,6,6,6,6,6,6,6,6},};
void dfs(int v){
    int f=81,o,ma=0,x,y,s;
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            if(mp[i][j]!=-1)continue;
            f--;
            o=(r[i]|c[j]|g[id[i][j]]);
            if(o==(1<<9)-1)return;
            if(__builtin_popcount(o)>=ma){
                x=i,y=j;
                ma=__builtin_popcount(o);
                s=o;
            }
        }
    }
    if(f==81){
        ans=max(ans,v);return;
    }
    for(int ch=8;ch>=0;ch--){
        if(!((s>>ch)&1)){
            mp[x][y]=ch;
            r[x]|=(1<<ch);
            c[y]|=(1<<ch);
            g[id[x][y]]|=(1<<ch);
            dfs(v+sc[x][y]*(ch+1));
            mp[x][y]=-1;
            r[x]&=(~(1<<ch));
            c[y]&=(~(1<<ch));
            g[id[x][y]]&=(~(1<<ch));
        }
    }
}
int main(){
    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            scanf("%d",&mp[i][j]);
            mp[i][j]--;id[i][j]=i/3*3+j/3;
            if(mp[i][j]!=-1){
                cs+=mp[i][j]*sc[i][j]+sc[i][j];
                r[i]|=(1<<mp[i][j]);
                c[j]|=(1<<mp[i][j]);
                g[id[i][j]]|=(1<<mp[i][j]);
            }
        }
    }
    dfs(cs);
    if(ans==0)printf("-1");
    else printf("%d",ans);
	return 0;
}

AcWing 184. 虫食算

对于每个x,y,z三元组,仅为只能是0或1,依次进行判断可行性

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,num[30],fd,j[30],vis[30];
char a[30],b[30],c[30];
bool pd(){
    int f=1;
    for(int i=1;i<=n;i++){
        int p=num[a[i]-'A'+1],q=num[b[i]-'A'+1],r=num[c[i]-'A'+1];
        if(p&&q&&r){
            if(f){
                if((p+q+j[i-1]-2)%n!=r-1)return 0;
                j[i]=(p+q+j[i-1]-2)/n;
            }
            else{
                if((p+q+1-2)%n!=r-1&&(p+q-2)%n!=r-1)return 0;
            }
            
        }
        else{
            f=0;
        } 
    }
    return 1;
}
void dfs(int x){
    if(fd)return ;
    if(x==n+1){
        for(int i=1;i<=n;i++){
            printf("%d ",num[i]-1);
        }fd=1;
        return ;
    }
    int p=num[a[x]-'A'+1],q=num[b[x]-'A'+1],r=num[c[x]-'A'+1];
    //printf("%d %d %d\n",p,q,r);
    if(p&&q&&r){
        if(pd())dfs(x+1);
    }
    
    else if(p&&q){
        if(!vis[(p+q+j[x-1]-2)%n+1]){
            num[c[x]-'A'+1]=(p+q+j[x-1]-2)%n+1;
            vis[(p+q+j[x-1]-2)%n+1]=1;
            if(pd())dfs(x+1);
            vis[(p+q+j[x-1]-2)%n+1]=0;;
            num[c[x]-'A'+1]=0;
        }
    }
    else if(p&&r){
        if(!vis[(n*2+r-j[x-1]-p)%n + 1] ){
            num[b[x]-'A'+1]=(n*2+r-j[x-1]-p)%n+1;
            vis[(n*2+r-j[x-1]-p)%n+1]=1;
            if(pd())dfs(x+1);
            vis[(n*2+r-j[x-1]-p)%n+1]=0;
            num[b[x]-'A'+1]=0;
        }
        
    }
    else if(q&&r){
        if(!vis[(n*2+r-j[x-1]-q)%n+1]){
            num[a[x]-'A'+1]=(n*2+r-j[x-1]-q)%n+1;
            vis[(n*2+r-j[x-1]-q)%n+1]=1;
            if(pd())dfs(x+1);
            vis[(n*2+r-j[x-1]-q)%n+1]=0;
            num[a[x]-'A'+1]=0;
        }
        
    }
    else if(!p){
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                num[a[x]-'A'+1]=i;
                vis[i]=1;
                if(pd())dfs(x);
                vis[i]=0;
                num[a[x]-'A'+1]=0;
            }
        }
    }
    else if(!q){
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                num[b[x]-'A'+1]=i;
                vis[i]=1;
                if(pd())dfs(x);
                vis[i]=0;
                num[b[x]-'A'+1]=0;
            }
        }   
    }
}
int main(){
    scanf("%d%s%s%s",&n,a+1,b+1,c+1);
    for(int i=1;i<=n/2;i++)swap(a[i],a[n-i+1]);
    for(int i=1;i<=n/2;i++)swap(b[i],b[n-i+1]);
    for(int i=1;i<=n/2;i++)swap(c[i],c[n-i+1]);
    dfs(1);
	return 0;
}

AcWing 185. 玛雅游戏

纯模拟,hash记录状态

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int n=5,m=7;
int mp[10][10],lim,fd,d[100005][10][10],tot,bj[10][10],h[10][10];
unordered_map<unsigned long long,bool>M[7];
void print(){for(int j=m;j>=1;j--){
    for(int i=1;i<=n;i++){
        
            printf("%d ",mp[i][j]);
        
        
    }puts("");}
    puts("");
}
struct S{
    int x,y,f;
}a[6];
bool check(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(mp[i][j])return 0;
        }
    }
    return 1;
}
void hs(int t){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            mp[i][j]=d[t][i][j];
        }
    }
}
int gx(){
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)bj[i][j]=0;
    for(int i=1;i<=n;i++){
        for(int j=2;j<=m;j++){
            int x=i,y=j;
            while(y-1>=1&&mp[x][y]&&mp[x][y-1]==0){
                swap(mp[x][y],mp[x][y-1]);
                y--;
            }
        }
    }
    int f=1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i-1>=1&&i+1<=n&&mp[i][j]&&mp[i+1][j]&&mp[i-1][j]&&mp[i][j]==mp[i+1][j]&&mp[i][j]==mp[i-1][j]){
                f=0;bj[i][j]=bj[i+1][j]=bj[i-1][j]=1;//cout<<i<<" "<<j<<endl;
            }
            if(j-1>=1&&j+1<=m&&mp[i][j]&&mp[i][j-1]&&mp[i][j+1]&&mp[i][j]==mp[i][j+1]&&mp[i][j]==mp[i][j-1]){
                f=0;bj[i][j]=bj[i][j+1]=bj[i][j-1]=1;
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(bj[i][j]==1)mp[i][j]=0;
        }
    }
    if(!f)gx();
    return f;
} 
bool pd(int x){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            h[i][j]=h[i-1][j]*1331+h[i][j-1]*131-h[i-1][j-1]*131*1331+mp[i][j]+1;
        }
    }
    if(M[x][h[n][m]]){
        return 0;
    }
    else{
       M[x][h[n][m]]=1;
       return 1; 
    }
}
void dfs(int x){
    //print();
    if(fd)return ;
    if(check()){
        if(x==lim+1){
            for(int i=1;i<=lim;i++){
                printf("%d %d %d\n",a[i].x-1,a[i].y-1,a[i].f);
            }
            fd=1;
        }
        return ;
    }
    if(x==lim+1)return;
    int t=++tot;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            d[t][i][j]=mp[i][j];
        }
    }
    int f;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(mp[i][j]){
                
                if(i!=n){
                    swap(mp[i][j],mp[i+1][j]);
                    gx();
                    a[x]={i,j,1};
                    if(pd(x))dfs(x+1);
                    hs(t);
                }
                
                if(i!=1){
                    swap(mp[i][j],mp[i-1][j]);
                    gx();
                    a[x]={i,j,-1};
                    if(pd(x))dfs(x+1);
                    hs(t);
                }
            }
        }
    }
}
int main(){
    cin>>lim;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m+1;j++){
            scanf("%d",&mp[i][j]);
            if(!mp[i][j])break;
        }
    }
    dfs(1);
    if(!fd)printf("%d",-1);
	return 0;
}

二.迭代加深

AcWing 170. 加成序列

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,cab[105],fd;
void dfs(int x,int lim){
    int mp[105]={0};
    if(fd)return;
    if(cab[x-1]==n){
        for(int i=1;i<x;i++){
            printf("%d ",cab[i]);
        }
        printf("\n");
        fd=1;return;
    }
    if(x>lim)return;
    for(int i=x-1;i>=1;i--){
        for(int j=i;j>=1;j--){
            if(cab[i]+cab[j]<=n&&mp[cab[i]+cab[j]]==0&&cab[i]+cab[j]>cab[x-1]){
                cab[x]=cab[i]+cab[j];
                mp[cab[i]+cab[j]]=1;
                dfs(x+1,lim);
            }
        }
    }
}
int main(){
    while(scanf("%d",&n)&&n){
        if(n==1){
            printf("1\n");
            continue; 
        } 
        fd=0;
        cab[1]=1;
        for(int i=2;i<=n;i++){
            dfs(2,i);
            if(fd)break;
        } 
    }
	return 0;
}

AcWing 186. 巴士

*先预处理出所有可能的数列,然后进行拼凑,化指数为组合

考虑剪枝:

1.优化搜索顺序:按点的个数对数列排序,

2.排除等效冗余:若后面几层都假设放最多还达不到n,直接回溯、

3.迭代加深

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,bus[70],fd; 
struct S{
    int n,a,d;
};
vector<S>f;
bool check(int a,int d){
    for(int i=a;i<60;i+=d)if(!bus[i])return 0;
    return 1;
}
bool cmp(S a,S b){
    return a.n>b.n;
}
void dfs(int dep,int k,int num){
    //cout<<dep<<" "<<k<<" "<<num<<endl;
    if(fd==1)return;
    if(!dep){
        if(num==n)fd=1;
        return;
    }
    for(int i=k;i<f.size();i++){
        if(!check(f[i].a,f[i].d))continue;
        if(f[i].n*dep+num<n)continue;
        for(int j=f[i].a;j<60;j+=f[i].d)bus[j]--;
        dfs(dep-1,i,num+f[i].n);
        for(int j=f[i].a;j<60;j+=f[i].d)bus[j]++;
    }
     
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        int x;scanf("%d",&x);bus[x]++;
    }
    for(int a=0;a<60;a++){
        for(int d=a+1;d+a<60;d++){
            if(check(a,d))f.push_back({(59-a)/d+1,a,d});
        }
    }
    sort(f.begin(),f.end(),cmp);
    for(int i=1;i<=17;i++){
        dfs(i,0,0);
        if(fd){
            printf("%d",i);
            break;
        }
    }
	return 0;
}

AcWing 187. 导弹防御系统

首先,对于每一个数,要不up[],要不down[],两种分支

其次,想到贪心,以up[]为例,如果能放则放(这个当时没想到),而且接在最大的能接的后面

最后,迭代加深即可

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,a[55];
int up[55],down[55],t1,t2;

bool dfs(int x,int lim){
    if(t1+t2>lim)return 0;

    
    if(x==n+1)return 1;
    
    int m=0,id=0;
    for(int i=1;i<=t1;i++){
        if(up[i]<a[x]&&up[i]>m){
            m=up[i],id=i;
        }
    }
    if(id){
        up[id]=a[x];
        if(dfs(x+1,lim))return 1;
        up[id]=m;
    }
    else{
        up[++t1]=a[x];
        if(dfs(x+1,lim))return 1;
        t1--;
    }
    m=1e9,id=0;
    for(int i=1;i<=t2;i++){
        if(down[i]>a[x]&&m>down[i]){
            m=down[i],id=i;
        }
    }
    if(id){
        down[id]=a[x];
        if(dfs(x+1,lim))return 1;
        down[id]=m;
        
    }
    else{
        down[++t2]=a[x];
        if(dfs(x+1,lim))return 1;
        t2--;
        
    }
    return 0;
}
int main(){
    while(~scanf("%d",&n)&&n){
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=n;i++){
            if(dfs(1,i)){
                t1=0,t2=0;
                printf("%d\n",i);
                //print();
                break;
            }
        }
    }
	return 0;
}

三、双向搜索

AcWing 171. 送礼物

先搜前一段,后一段二分查找匹配

attention:lowerbound满

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
long long w,n,cnt[1<<25],a[50],k,tot,ans;
long long erf(long long x){
    int l=1,r=tot,res;
    while(l<=r){
        int mid=(l+r)>>1;
        if(x+cnt[mid]<=w){
            l=mid+1;
            res=mid;
        }
        else{
            r=mid-1;
        }
    }
    return cnt[res];
}
void dfs(int x,long long v){
    if(x==k+1){
        cnt[++tot]=v;return ;
    }
    if(a[x]+v<=w){
        dfs(x+1,a[x]+v);
    }
    dfs(x+1,v);
}
void dfs2(int x,long long v){
    if(x==n+1){
        ans=max(ans,v+erf(v));
        return ;
    }
    if(a[x]+v<=w){
        dfs2(x+1,a[x]+v);
    }
    dfs2(x+1,v);
}
int main(){
    scanf("%lld%lld",&w,&n);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    k=n/2;
    dfs(1,0);
    sort(cnt+1,cnt+tot+1);
    tot=unique(cnt+1,cnt+tot+1)-cnt-1;
    dfs2(k+1,0);
    printf("%lld",ans);
    
	return 0;
}
相关推荐
爱代码的小黄人2 小时前
深入解析系统频率响应:通过MATLAB模拟积分器对信号的稳态响应
开发语言·算法·matlab
是僵尸不是姜丝5 小时前
每日算法:洛谷U535992 J-C 小梦的宝石收集(双指针、二分)
c语言·开发语言·算法
寒页_7 小时前
2025年第十六届蓝桥杯省赛真题解析 Java B组(简单经验分享)
java·数据结构·经验分享·算法·蓝桥杯
smile-yan7 小时前
拓扑排序 —— 2. 力扣刷题207. 课程表
数据结构·算法·图论·拓扑排序
空雲.8 小时前
牛客周赛88
数据结构·c++·算法
深度学习算法与自然语言处理8 小时前
单卡4090微调大模型 DeepSeek-R1-32B
深度学习·算法·大模型·微调·transformer·面试题
Y1nhl8 小时前
基础算法:滑动窗口_python版本
开发语言·python·算法·力扣·滑动窗口
烟锁池塘柳08 小时前
【数学建模】(智能优化算法)鲸鱼优化算法(Whale Optimization Algorithm)详解与应用
算法·数学建模
地平线开发者9 小时前
【征程 6】工具链 VP 示例中 Cmakelists 解读
算法·自动驾驶
邪神与厨二病9 小时前
2025蓝桥杯python A组题解
数据结构·c++·python·算法·蓝桥杯·单调栈·反悔贪心