zoukankan      html  css  js  c++  java
  • 0x21 剪枝

    这一章真是心态崩,剪枝太玄学啦,特别是那个搜索顺序我靠真的。。。

    poj1011 枚举答案,搜索记录当前到第几根木棒。 剪枝:1、从大到小排序 2、排除等效,这个感觉还行,就是木棒按大小顺序进去,去除顺序不同的相同的情况,相同的木棒也是不用管的。  好的前面这些都可以想,关键是第三个,拼接第一个失败就全部重来。这个真是没想到

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int n,L,C,c[110];
    bool cmp(int x,int y){return x>y;}
    bool v[110];
    bool dfs(int k,int len,int last)
    {
        if(k==C+1)return true;
        if(len==L)return dfs(k+1,0,0);
        
        int fail=0;
        for(int i=last+1;i<=n;i++)
        {
            if(v[i]==false&&len+c[i]<=L&&c[i]!=fail)
            {
                v[i]=true;
                if(dfs(k,len+c[i],i))return true;
                v[i]=false;
                fail=c[i];
                if(len==0)return false;
            }
        }
        return false;
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            if(n==0)break;
            
            int sum=0;
            for(int i=1;i<=n;i++)
                scanf("%d",&c[i]), sum+=c[i];
            sort(c+1,c+n+1,cmp);
            
            int mmin=2147483647;
            for(int i=1;i*i<=sum;i++)
                if(sum%i==0)
                {
                    if(i<mmin)
                    {
                        L=i, C=sum/i;
                        memset(v,false,sizeof(v));
                        if(dfs(1,0,0)==true)mmin=min(mmin,i);
                    }
                    if(sum/i<mmin&&i*i!=sum)
                    {
                        L=sum/i, C=i;
                        memset(v,false,sizeof(v));
                        if(dfs(1,0,0)==true)mmin=min(mmin,sum/i);
                    }
                }
            printf("%d
    ",mmin);
        }
        return 0;
    }
    poj1011

    poj1190 这题简直就是剪枝的代表作了。。。我可以算是想出了1.5+2??个trick,但是这题整整五个剪枝啊!!!

    1、大小,看到这个我都快条件反射了,管他有的没的倒序就是没错的

    2、上下界,这个我想得还要复杂一点,导致有点难算,lyd就很暴力了直接开根

    3、4、对于体积和表面积,到达目标的最小花费+当前花费比限制、当前最小花费大,那么就剪掉。我纠结了一会为啥一个叫可行性剪枝一个叫最优性剪枝,是因为体积是确定的而表面积是要求的

    5、最***玄学的就是这个不等式了,上面全部的体积可以表示成sigema(1~dep-1)h[i]*r[i]^2,表面积就是2*sigema(1~dep-1)h[i]*r[i], 假设当前已经的体积为V

    2*sigema(1~dep-1)h[i]*r[i] = 2/r[dep]*sigema(1~dep-1)h[i]*r[i]*r[dep] >= 2/r[dep]*sigema(1~dep-1)h[i]*r[i]*r[i] = 2*(N-V)/r[dep] 这个时候又可以判表面积。。。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int N,m,mmin,r[11000],h[11000];
    int minV[30],minS[30];
    void dfs(int k,int V,int S)
    {
        if(minV[k]+V>N)return ;
        if(minS[k]+S>mmin)return ;
        if(2*(N-V)/r[k+1]+S>mmin)return ;
        if(k==0)
        {
            if(minV[k]+V==N)mmin=min(mmin,S);
            return ;
        }
        
        int Rli=min( int(sqrt(double(N-V+1))) , r[k+1]-1 );
        for(int R=Rli;R>=k;R--)
        {
            int Hli=min( (N-V)/(R*R) , h[k+1]-1 );
            for(int H=Hli;H>=k;H--)
            {
                r[k]=R;h[k]=H;
                dfs(k-1,V+R*R*H,S+2*R*H+((k==m)?R*R:0));
            }
        }
    }
    int main()
    {
        scanf("%d%d",&N,&m);
        for(int i=1;i<=m;i++)
            minV[i]=i*i*i+minV[i-1], minS[i]=2*i*i+minS[i-1];
        
        mmin=2147483647;
        r[m+1]=h[m+1]=2147483647;
        dfs(m,0,0);
        printf("%d
    ",mmin);
        return 0;
    }
    poj1190

    poj3076 状压,判点,判字母,绝望,留坟

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<bitset>
    using namespace std;
    
    int cnt;
    char ss[20][20],sc[310][20][20];
    bitset<16>mp[20][20],tt[310][20][20],ts[310][20][20];
    void init()
    {            
        memset(mp,0,sizeof(mp));
        for(int j=1;j<=16;j++)//
        {
            int zt=0;
            for(int i=1;i<=16;i++)
                if(ss[i][j]!='-')
                    zt|=(1<<(ss[i][j]-'A'));
            for(int i=1;i<=16;i++) mp[i][j]|=zt;
        }
        for(int i=1;i<=16;i++)//
        {
            int zt=0;
            for(int j=1;j<=16;j++)
                if(ss[i][j]!='-') 
                    zt|=(1<<(ss[i][j]-'A'));
            for(int j=1;j<=16;j++) mp[i][j]|=zt;
        }
        for(int i=1;i<=16;i+=4)
            for(int j=1;j<=16;j+=4)
            {
                int zt=0;
                for(int k=1;k<=4;k++)
                    for(int l=1;l<=4;l++)
                        if(ss[i+k-1][j+l-1]!='-')
                            zt|=(1<<(ss[i+k-1][j+l-1]-'A'));
                for(int k=1;k<=4;k++)
                    for(int l=1;l<=4;l++)
                            mp[i+k-1][j+l-1]|=zt;
            }
            
        cnt=0;
        for(int i=1;i<=16;i++)
            for(int j=1;j<=16;j++)
            {
                if(ss[i][j]=='-')cnt++;
                mp[i][j].flip();
            }
    }
    
    bitset<16>p;bool v[16];
    bool check()
    {
        for(int i=1;i<=16;i++)
            for(int j=1;j<=16;j++)
                if(mp[i][j]==0&&ss[i][j]=='-')return false;
        
        for(int i=1;i<=16;i++)
        {
            p.reset();memset(v,false,sizeof(v));
            for(int j=1;j<=16;j++)
            {
                if(ss[i][j]!='-')v[ss[i][j]-'A']=true;
                else p|=mp[i][j];
            }
            for(int o=0;o<=15;o++)
                if(p[o]==0&&v[o]==false)return false;
        }
        for(int j=1;j<=16;j++)
        {
            p.reset();
            for(int i=1;i<=16;i++)
            {
                if(ss[i][j]!='-')v[ss[i][j]-'A']=true;
                else p|=mp[i][j];
            }
            for(int o=0;o<=15;o++)
                if(p[o]==0&&v[o]==false)return false;
        }
        for(int i=1;i<=16;i+=4)
            for(int j=1;j<=16;j+=4)
            {
                p.reset();memset(v,false,sizeof(v));
                for(int k=1;k<=4;k++)
                    for(int l=1;l<=4;l++)
                    {
                        if(ss[i+k-1][j+l-1]!='-')v[ss[i+k-1][j+l-1]-'A']=true;
                        else p|=mp[i+k-1][j+l-1];
                    }
            for(int o=0;o<=15;o++)
                if(p[o]==0&&v[o]==false)return false;
            }
        return true;
    }
    void influence(int x,int y)
    {
        int o=ss[x][y]-'A';
        for(int j=1;j<=16;j++)mp[x][j][o]=0;
        for(int i=1;i<=16;i++)mp[i][y][o]=0;
        
        int i=((x-1)/4)*4+1,j=((y-1)/4)*4+1;
        for(int k=1;k<=4;k++)
            for(int l=1;l<=4;l++)
                mp[i+k-1][j+l-1][o]=0;
    }
    bool bk;
    void dfs(int k,int dep)
    {
        if(bk==true)return ;
            
        memcpy(ts[dep],mp,sizeof(ts[dep]));
        memcpy(sc[dep],ss,sizeof(sc[dep]));
        bool qwq=true;
        while(qwq)
        {
            qwq=false;
            for(int i=1;i<=16;i++)
                for(int j=1;j<=16;j++)
                {
                    if(ss[i][j]=='-'&&mp[i][j].count()==1)
                    {
                        k--;qwq=true;
                        for(int o=0;o<=15;o++)
                            if(mp[i][j][o]==1)
                            {
                                ss[i][j]='A'+o;
                                influence(i,j);
                                break;
                            }
                    }
                }
            for(int o=1;o<=16;o++)
            {
                for(int i=1;i<=16;i++)
                {
                    int u=0,jj;
                    for(int j=1;j<=16;j++)
                        if(mp[i][j][o]==1)
                        {
                            u++;jj=j;
                            if(u==2)break;
                        }
                    if(u==1)
                    {
                        ss[i][jj]='A'+o;
                        influence(i,jj);
                    }
                }
                for(int j=1;j<=16;j++)
                {
                    int u=0,ii;
                    for(int i=1;i<=16;i++)
                        if(mp[i][j][o]==1)
                        {
                            u++;ii=i;
                            if(u==2)break;
                        }
                    if(u==1)
                    {
                        ss[ii][j]='A'+o;
                        influence(ii,j);
                    }
                }
                for(int i=1;i<=16;i+=4)
                    for(int j=1;j<=16;j+=4)
                    {
                        int u=0,ii,jj;
                        for(int k=1;k<=4;k++)
                            for(int l=1;l<=4;l++)
                            {
                                if(mp[i+k-1][j+l-1][o]==1)
                                {
                                    u++;ii=i;jj=j;
                                    if(u==2)break;
                                }
                            }
                        if(u==1)
                        {
                            ss[ii][jj]='A'+o;
                            influence(ii,jj);
                        }
                    }
            }
        }//必定赋值 
        if(!check())
        {
            memcpy(mp,ts[dep],sizeof(mp));
            memcpy(ss,sc[dep],sizeof(ss));
            return ;
        }
        
        if(k==0)
        {
            bk=true;
            for(int i=1;i<=16;i++)
            {
                for(int j=1;j<=16;j++)printf("%c",ss[i][j]);
                printf("
    ");
            }
            return ;
        }
        
        int cc=999999,nx,ny;
        for(int i=1;i<=16;i++)
            for(int j=1;j<=16;j++)
                if(ss[i][j]=='-'&&mp[i][j].count()<cc)
                {
                    cc=mp[i][j].count();
                    nx=i,ny=j;
                }
        for(int o=0;o<=15;o++)
            if(mp[nx][ny][o]==1)
            {
                memcpy(tt[dep],mp,sizeof(tt[dep]));
                ss[nx][ny]='A'+o;
                
                influence(nx,ny);
                if(check())
                    dfs(k-1,dep+1);
                
                ss[nx][ny]='-';
                memcpy(mp,tt[dep],sizeof(mp));
            }
            
        memcpy(mp,ts[dep],sizeof(mp));
        memcpy(ss,sc[dep],sizeof(ss));
    }
    int main()
    {
        for(int i=1;i<=16;i++)scanf("%s",ss[i]+1);
        init();
        
        bk=false;dfs(cnt,1);
        return 0;
    }
    poj3076(TLE)
  • 相关阅读:
    docker 会这些也够
    Linux 学会这些基本可以啦
    xxxxxxxxx
    Angular
    mongo
    node
    git clone 解决Permission Denied (publickey)问题
    vue项目如何刷新当前页面
    vue——动态路由以及地址传参
    vue 单页应用点击某个链接,跳转到新页面的方式
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9270091.html
Copyright © 2011-2022 走看看