【刷题】【dp】蓝桥·回路计数

普通的哈密顿回路状态压缩模型,但是wa了两天

 

第一次是时间复杂度过大,调整了循环的嵌套顺序,由n*(1<<n)的复杂度改成了每个状态只遍历一次

    f[1][1]=true;
    for(int i=1;i<n;i++)
    {
        int sz=st[i].size();
        for(int j=0;j<sz;j++)
        {
            int sta=st[i][j];
            for(int p=1;p<=n;p++)
            {
                if(!f[p][sta] ) continue;
                if((sta%mod[p+1]/mod[p])==0 ) continue;
                for(int q=1;q<=n;q++)
                {
                    if(!g[p][q] ) continue;
                    if((sta%mod[q+1]/mod[q])==1 ) continue;
                    f[q][sta^mod[q]]+=f[p][sta];
                }
            }
        }
    }

第二次是提交的时候只屏蔽了主函数,其他函数没删,莫名其妙运行错误了

所以蓝桥的填空题,代码要记得删干净啊

//n+1 + C(n+1,2) 
 
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read()
{
    int f=1,x=0; char c=getchar();
    while(c<'0' || c>'9' ) 
    {
        if(c=='-' )    f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9' ) x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x*f;
}

int gcd(int a,int b)
{
    if(a==0 ) return b;
    else return gcd(b%a,a);
}

const int n=21;
const int mx=(1<<n)-1;
bool g[30][30];
vector <int > st[30];
ll f[30][mx];
int mod[30];

int Cnt(int x)
{
    int cnt=0;
    while(x )
    {
        if((x&1)==1 ) cnt++;
        x>>=1;
    }
    return cnt;
}

int main()
{
    cout<<881012367360;
    cout<<544071680;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(i!=j && gcd(i,j)==1 )
                g[i][j]=true;
    
    for(int i=1;i<=mx;i++)
        st[Cnt(i)].push_back(i);
    mod[1]=1;
    for(int i=1;i<=n;i++) 
        mod[i+1] = (mod[i]<<1);
    
    f[1][1]=true;
    for(int i=1;i<n;i++)
    {
        int sz=st[i].size();
        for(int j=0;j<sz;j++)
        {
            int sta=st[i][j];
            for(int p=1;p<=n;p++)
            {
                if(!f[p][sta] ) continue;
                if((sta%mod[p+1]/mod[p])==0 ) continue;
                for(int q=1;q<=n;q++)
                {
                    if(!g[p][q] ) continue;
                    if((sta%mod[q+1]/mod[q])==1 ) continue;
                    f[q][sta^mod[q]]+=f[p][sta];
                }
            }
        }
    }
    ll ans=0;
    for(int i=2;i<=n;i++)
        ans+=f[i][mx],cout<<" "<<f[i][mx]<<endl;
    cout<<ans<<endl;
    return 0;
}
View Code

 

posted @ 2022-03-28 01:05  心若笺诗  阅读(37)  评论(0编辑  收藏  举报