CF11D A Simple Task

Posted qyj060604

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF11D A Simple Task相关的知识,希望对你有一定的参考价值。

垃圾状压dp,应该根本没有紫题难度     

设当前状态为state,起点为state包含的元素中最小的一个,防止重复,以及当前所在地点u    

注意自环,就是两个点来回走的。在答案里修改也可以。我是直接在ans更新时判断state是否合法,是否包含至少3个元素      

然后一个答案会两种时针方式走,所以最终答案要处以2    

代码:      

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll f[20][600005]=0,ans=0;
int n,m;
int hed[5005],tal[5005],nxt[5005],cnt=0;
inline void addege(int x,int y)
    cnt++;
    tal[cnt]=y;
    nxt[cnt]=hed[x];
    hed[x]=cnt;
 
bool ck(int state)
    int cnt=0;
    for(int i=1;i<=n;i++)
        if((state&(1<<(i-1)))==(1<<(i-1)))
            cnt++;
        
    
    if(cnt<=2) return 0;
    return 1;

int main()
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        int x,y;
        scanf("%d%d",&x,&y);
        addege(x,y);
        addege(y,x);
    
    for(int i=1;i<=n;i++)
        f[i][1<<(i-1)]=1ll; 
     
    for(int state=1;state<(1<<n);state++)
        int st,u;
        for(int i=1;i<=n;i++)
            if((state&(1<<(i-1)))==(1<<(i-1)))
                st=i;
                break;
            
        
        for(int i=1;i<=n;i++)
            if((state&(1<<(i-1)))!=(1<<(i-1))) continue;
            u=i;
            for(int j=hed[u];j;j=nxt[j])
                int v=tal[j];
                if(v<st) continue;
                if((state&(1<<(v-1)))==(1<<(v-1)))
                    if(v==st&&ck(state)) ans+=f[u][state]/*printf("st:%d,state:%d,f[u][state]:%d\n",st,state,f[u][state])*/;
                
                else f[v][state|(1<<(v-1))]+=f[u][state];
            
        
    
    cout<<ans/2<<endl;
    return 0;
 

 

以上是关于CF11D A Simple Task的主要内容,如果未能解决你的问题,请参考以下文章

CF 11D A Simple Task 题解

CF11D A Simple Task(状压DP)

CF11D A Simple Task 状压DP

CodeForces - 11D A Simple Task

[CodeForces 11D] A Simple Task - 状态压缩入门

CodeForces 11D A Simple Task