• 状态压缩+升维dp——UCF 2016 I


    两种dp状态的设置法

    比较坑的一个地方:不论是哪种设置法,最后都要特判一下所有骨牌相同的情况,这种情况要把最后的结果/2

      因为此时每种骨牌排列,都可以将每块骨牌逆过来,还是合法的,基于我们设置的状态,这样就多统计了一倍,所以要/2

      只要有一块骨牌和其他不同,上述情况就不成立

    此外:当s[i]==t[i]时,我们只挑选一个计算贡献即可

    1.dp[S][i]:当前状态集合为S,末尾是i

    /*
    dp[01][1]=1
    dp[01][2]=1
    dp[10][1]=1
    dp[10][2]=1
    dp[11][1]=1
    dp[11][2]=1
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long 
    #define mod 1000000007
    
    ll dp[1<<17][17],s[20],t[20],n;
    
    int main(){
        int T;cin>>T;
        while(T--){
            cin>>n;
            int flag=0;
            for(int i=0;i<n;i++){
                cin>>s[i]>>t[i];
                if(!(s[i]==s[0] && t[i]==t[0] || s[i]==t[0] && t[i]==s[0]))
                    flag=1;
            }
            if(!flag){
                ll ans=1;
                for(int i=1;i<=n;i++)
                    ans=ans*i%mod;
                cout<<ans<<'
    ';continue;
            }
            memset(dp,0,sizeof dp);
            
            dp[0][0]=1; 
            for(int S=0;S<(1<<n);S++){//当前状态是S 
                for(int i=0;i<n;i++)if(!(S>>i & 1)){
                    //把第i块放在最后的方案数
                    if(S==0){
                        dp[S|(1<<i)][s[i]]=(dp[S|(1<<i)][s[i]]+dp[S][0])%mod;
                        if(s[i]!=t[i])
                            dp[S|(1<<i)][t[i]]=(dp[S|(1<<i)][t[i]]+dp[S][0])%mod;
                    }
                    else  {
                        dp[S|(1<<i)][s[i]]=(dp[S|(1<<i)][s[i]]+dp[S][t[i]])%mod;
                        if(s[i]!=t[i])
                            dp[S|(1<<i)][t[i]]=(dp[S|(1<<i)][t[i]]+dp[S][s[i]])%mod;
                    }
                }
            }
            
            long long ans=0;
            for(int i=1;i<=6;i++)
                ans=(ans+dp[(1<<n)-1][i])%mod;
            cout<<ans<<'
    ';               
        }
    }

    2.dp[S][i][0|1] 状态集合S,最后一个是骨牌i,0|1正放,逆放

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long 
    #define mod 1000000007
    
    ll dp[1<<17][17][2],s[20],t[20],n;
    
    int main(){
        int T;cin>>T;
        while(T--){
            cin>>n;
            int flag=0;
            for(int i=0;i<n;i++){
                cin>>s[i]>>t[i];
                if(!(s[i]==s[0] && t[i]==t[0] || s[i]==t[0] && t[i]==s[0]))
                    flag=1;
            }
            if(!flag){
                ll ans=1;
                for(int i=1;i<=n;i++)
                    ans=ans*i%mod;
                cout<<ans<<'
    ';continue;
            }
            
            memset(dp,0,sizeof dp);
            
            dp[0][0][0]=1; 
            for(int S=0;S<(1<<n);S++){//当前状态是S 
                if(S==0){
                    for(int i=0;i<n;i++){
                        dp[S|(1<<i)][i][0]=(dp[S|(1<<i)][i][0]+1)%mod;
                        dp[S|(1<<i)][i][1]=(dp[S|(1<<i)][i][1]+1)%mod;
                    }
                    continue;
                }
                for(int i=0;i<n;i++)if(S>>i & 1){//最后一块是i 
                    for(int j=0;j<n;j++)if(!(S>>j & 1)){
                        if(s[j]==t[i])
                            dp[S|(1<<j)][j][0]=(dp[S|(1<<j)][j][0]+dp[S][i][0])%mod;
                        if(s[j]==s[i] && s[i]!=t[i])
                            dp[S|(1<<j)][j][0]=(dp[S|(1<<j)][j][0]+dp[S][i][1])%mod;
                    
                        if(t[j]==t[i])
                            dp[S|(1<<j)][j][1]=(dp[S|(1<<j)][j][1]+dp[S][i][0])%mod;
                        if(t[j]==s[i] && s[i]!=t[i])
                            dp[S|(1<<j)][j][1]=(dp[S|(1<<j)][j][1]+dp[S][i][1])%mod;
                    }
                }
            }
            
            long long ans=0;
            for(int i=0;i<n;i++){
                ans=(ans+dp[(1<<n)-1][i][0])%mod;
                if(s[i]!=t[i])
                    ans=(ans+dp[(1<<n)-1][i][1])%mod;
            }
            cout<<ans<<'
    ';
        }
    }
  • 相关阅读:
    Ext.Msg.alert要注意的问题
    项目终于到了可以轻松下的时候,^_^
    Ext最佳应用
    Google居然无视中国人民的感情
    google的logo居然还是鲜艳色的!!!(下午已经是黑的了,还是感谢google)
    我们必须支持国产,这是义务
    管理软件更需要Open Social
    设计模式外观模式(Facade)
    设计模式代理模式(Proxy)
    设计模式桥接模式(Bridge)
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12602067.html
Copyright © 2020-2023  润新知