题目传送门

又是一道状压+计数类好题hh(真香)。数据范围非常友好,告诉我们\(n<=18\),非常符合状压的性质。

其实感觉和\(Hamilton\)路径那题还是有些相似的,我们可以类似地设计出状态:\(f[i][j][w]\)表示当前状态为\(i\),现在位于\(j\)点,体力耗费为\(w\)(\(w\)只有两种可能)的方案数。

我们考虑转移的时候向之后的状态转移,设\(i\)为当前的状态,\(j\)为上一个最后落在的位置,\(k\)是这一次最后落在的位置。因为有滑稽态&&奇偶态两种,所以有两种转移。因为边数在\(1e5\)的范围内,所以肯定是个稠密图,有很多很多重边,又因为本题数据范围很小,不妨直接用邻接矩阵存下两点间有多少重边。转移的时候就可以直接从上一方案乘上重边数转移过来。又注意到题中的\(sum()\)其实是可以预处理出来的,所以我们就先搞出来降低复杂度。

最后我们得到了转移方程:

(f[i|(1<<(k-1))][k][(0+k*st[i])%2]+=1ll*f[i][j][0]*cnt[k][j])%=moder;
(f[i|(1<<(k-1))][k][(1+k*st[i])%2]+=1ll*f[i][j][1]*cnt[k][j])%=moder;

\(Code\)

#include<cstdio>
#include<algorithm>
#define maxn 300000 using namespace std;
typedef long long ll;
const ll moder=19260817; int n,m,opt,fake;
ll ans,st[maxn],f[maxn][20][3];
int cnt[30][30]; int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x=0,y=0;
scanf("%d%d",&x,&y);
cnt[x][y]++,cnt[y][x]++;
}
scanf("%d",&opt);
fake=(1<<n)-1;
for(int i=0;i<=fake;i++)
for(int j=0;j<n;j++)
if(i&(1<<j)) st[i]+=j+1;
f[1][1][0]=1;
for(int i=0;i<=fake;i++)
for(int j=1;j<=n;j++)
{//枚举上一个位置
if(!(i&(1<<(j-1)))) continue;
for(int k=1;k<=n;k++)
{//枚举当前落到的位置
if(i&(1<<(k-1))) continue;
(f[i|(1<<(k-1))][k][(0+k*st[i])%2]+=1ll*f[i][j][0]*cnt[k][j])%=moder;
(f[i|(1<<(k-1))][k][(1+k*st[i])%2]+=1ll*f[i][j][1]*cnt[k][j])%=moder;
}
}
for(int i=0;i<=fake;i++)
(ans+=f[i][n][opt])%=moder;
printf("%lld\n",ans);
return 0;
}

另外注意审题:题面中的价值的描述十分清楚,路径集合\(A\)是加入\(m\)前的。所以在转移和赋初值的时候要明确这一点。我才不会告诉你开始的时候没注意这一点

Luogu P4892 GodFly的寻宝之旅【状压dp】By cellur925的更多相关文章

  1. [LuoguP4892]GodFly的寻宝之旅 状压DP

    链接 基础状压DP,预处理出sum,按照题意模拟即可 复杂度 \(O(n^22^n)\) #include<bits/stdc++.h> #define REP(i,a,b) for(in ...

  2. Luogu 2157 [SDOI2009]学校食堂 - 状压dp

    Solution 比较好想的dp, 但是坑不少QAQ, 调半天 由于容忍度 $b_i$<= 7, 所以可以考虑将第$i$个人接下来的$b_i$ 个人作为一个维度记录状态. 于是我们定义数组$f[ ...

  3. 洛谷 P3112 后卫马克 —— 状压DP

    题目:https://www.luogu.org/problemnew/show/P3112 状压DP...转移不错. 代码如下: #include<iostream> #include& ...

  4. 洛谷 3112 [USACO14DEC]后卫马克Guard Mark——状压dp

    题目:https://www.luogu.org/problemnew/show/P3112 状压dp.发现只需要记录当前状态的牛中剩余承重最小的值. #include<iostream> ...

  5. BZOJ 4042 Luogu P4757 [CERC2014]Parades (树形DP、状压DP)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4042 (Luogu) https://www.luogu.org/prob ...

  6. [Luogu P3959] 宝藏 (状压DP+枚举子集)

    题面 传送门:https://www.luogu.org/problemnew/show/P3959 Solution 这道题的是一道很巧妙的状压DP题. 首先,看到数据范围,应该状压DP没错了. 根 ...

  7. [Luogu P2831] 愤怒的小鸟 (状压DP)

    题面: 传送门:https://www.luogu.org/problemnew/show/P2831 Solution 首先,我们可以先康一康题目的数据范围:n<=18,应该是状压或者是搜索. ...

  8. [Luogu P2051] [AHOI2009]中国象棋 (状压DP->网格DP)

    题面 传送门:https://www.luogu.org/problemnew/show/P2051 Solution 看到这题,我们不妨先看一下数据范围 30pt:n,m<=6 显然搜索,直接 ...

  9. 【Luogu】P1896互不侵犯King(状压DP)

    题目链接 真是可恶,被数据范围坑了一把.想要一遍AC的希望破灭了…… 以后大家在做状压DP的时候一定要开long long…… 设f[i][j][k]表示考虑前i行,总共放了j个King,第i行状态为 ...

随机推荐

  1. 简单老式Java对象 横切关注点 最小侵入性编程 声明式编程 避免强迫类继承和接口实现

    Spring In Action data injection aspect-oriented programming Plain Old Java Object 依赖注入能让相互协作的软件组件保持松 ...

  2. TWinControl、TCustomControl和TGraphicControl对WM_PAINT消息的三种不同处理(虚函数的特点就是升升降降)

    -------------------- TWinControl收到WM_Paint消息(以后找个例子)-------------------- 1. 消息函数 TWinControl.WMPaint ...

  3. Virtualbox虚拟机安装RouterOS

    一,下载 vdi文件https://mikrotik.com/download Cloud Hosted Routerhttps://download.mikrotik.com/routeros/6. ...

  4. [CPP - STL] swap技巧

    最近在看<Effective STL>,[条款17:使用“交换技巧”修整过剩容量]中提到容器的成函数void swap(container& from),即实现容器对象与from对 ...

  5. redis一些笔记

    base 字典: hget/hset 在redis字典中值只能是字符串,使用渐进式进行rehash.在rehash的过程中,会保留两个hash结构:查询时会同时查询两个结构:逐渐完成hash的迁移. ...

  6. JavaSE基础练习IO,字符串,循环

    import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.F ...

  7. IOS开发学习笔记(2)-----UIButton 详解

    1. [代码][C/C++]代码     //这里创建一个圆角矩形的按钮    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRou ...

  8. Notepad++安装xml插件

    环境: win7 64位 Notepad++7.3.3 原生的Notepad++不自带xml文件的插件,所以在显示xml文件时并不分行(如下图所示),对于用户编辑,查看的操作而言,并不友好,所以需要安 ...

  9. apache web 服务器

    0. 特性与特点 性能方面,apache 在设计时采用了以"进程"为基础的结构,自然进程比线程消耗了更多的系统开销,导致了 apache 在多处理器环境中性能有所下降: 因此,在对 ...

  10. C++之new和delete

    new 和 delete 是 C++ 用于管理 堆内存 的两个运算符,对应于 C 语言中的 malloc 和 free,但是 malloc 和 free 是函数,new 和 delete 是运算符.除 ...