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的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces - 11D A Simple Task