zoukankan      html  css  js  c++  java
  • noi-openjudge[4.7搜索]怀表问题

    为啥我觉得这是个DP….f[i][j][k][l]表示四种零件分别用了i,j,k,l个的方案数。然后发现这样不能保证表一定能接在表链首尾,也不知道状态之间如何转移,那么加一维变成f[i][j][k][l][S],S表示首尾的状态(4种),于是就可以预处理了。然后我们需要从给出的一共n个4种零件中选出k个。那么dfs暴力枚举方案。

    一开始DP求的状态是i,j,k,l四维都取到1-40,算了一些冗余状态,T了……后来限制四维之和小于等于40,A了……不过慢死…好像别人是直接搜的,加个记忆化?因为真正用到的状态数目不多所以会比较快?

    #include<cstdio>
    typedef long long ll;
    ll f[45][45][45][45][4];//4:首-尾字母 
    void dp(){//并不是所有状态都会被用到? 
        f[1][0][0][0][0]=f[0][1][0][0][1]=f[0][0][1][0][2]=f[0][0][0][1][3]=1;
        for(int i=0;i<=40;++i){
            for(int j=0;i+j<=40;++j){
                for(int k=0;i+j+k<=40;++k){
                    for(int l=0;i+j+k+l<=40;++l){
                        if(i+j+k+l==1)continue;
                        for(int s=0;s<4;++s){
                            if(i!=0&&(s&1)==0)f[i][j][k][l][s]+=f[i-1][j][k][l][s];
                            if(j!=0&&(s&1)==1)f[i][j][k][l][s]+=f[i][j-1][k][l][s^1];
                            if(k!=0&&(s&1)==0)f[i][j][k][l][s]+=f[i][j][k-1][l][s^1];
                            if(l!=0&&(s&1)==1)f[i][j][k][l][s]+=f[i][j][k][l-1][s];
                        }
                    } 
                } 
            } 
        }
    }
    int cnt[4];
    int sol[4];
    ll ans=0;int S;
    int n,k;
    void dfs(int x,int sum){
        if(x==4){
            if(sum==0)ans+=f[sol[0]][sol[1]][sol[2]][sol[3]][S];
            return;
        }
        for(int i=0;i<=cnt[x]&&i<=sum;++i){
            sol[x]=i;
            dfs(x+1,sum-i);
            sol[x]=0;
        }
        
    }
    int main(){
        dp();
        char buf[3];
        while(scanf("%d%d",&n,&k)!=EOF){
            scanf("%s",buf);
            S=0;
            if(buf[0]=='V')S+=1;
            if(buf[1]=='V')S+=2;
            cnt[0]=cnt[1]=cnt[2]=cnt[3]=0;
            for(int i=1;i<=n;++i){
                scanf("%s",buf);
                int tmp=0;
                if(buf[0]=='V')tmp+=2;
                if(buf[1]=='V')tmp+=1;
                cnt[tmp]++;
            }  
            ans=0;
            dfs(0,k);
    
            if(ans==0)printf("NO
    ");
            else printf("YES
    %lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    数据结构之线性顺序表ArrayList(Java实现)
    大话数据库技术之数据的检索
    JQuery表单元素过滤选择器
    字典序最小问题
    liferay中数据库表的解析未完
    转载如何实现portlet之间的传递参数
    SpringMVC学习笔记1
    深度优先搜索算法
    Ants-穷举算法
    三角形-穷举算法
  • 原文地址:https://www.cnblogs.com/liu-runda/p/6049540.html
Copyright © 2011-2022 走看看