jzoj5990. 【北大2019冬令营模拟2019.1.6】Bear (状压dp)
题面


题解
我永远讨厌dp.jpg
搞了一个下午优化复杂度最后发现只要有一个小trick就可以A了→_→。全场都插头dp就我一个状压跑得贼慢……
不难发现我们可以状压,对于每一行,用状态\(S\)表示有哪些格子是已经被上一行推倒了的,那么我们可以枚举本行所有格子的字母情况,然后计算一下这个时候下一行格子被推倒的情况,把这一行的贡献加到下一行就行了。
简单来说就是记一个\(f[pos][S]\)表示第\(pos\)行,格子被推倒的情况为\(S\)时的方案数,\(dp[pos][S]\)为所有方案中推倒树的总数,那么假设一个选字母的方案会使下一行的推倒情况为\(S'\),会使这一行可以推倒\(k\)棵树,则有转移$$f[pos+1][S']+=f[pos][S]$$
\]
最后\(f[n+1][0]\)就是答案。这样的话能有\(40\)分(建议先看一下40分代码不然看不太懂AC代码的……)
//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
const int N=13,M=35,L=(1<<21)+5;
int a[N][M],f[N][L],dp[N][L],g[N][L],n,m,P,lim,ans,vis[N];
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
void solve(int pos){
fp(i,0,lim-1)if(f[pos][i]){
fp(j,0,lim-1){
int S=0,res=0;
fp(k,0,m-1)vis[k]=i&(1<<k);
fp(k,0,m-1)if(!vis[k]){
if(j&(1<<k)){
if(k!=m-1&&!vis[k+1])vis[k]=vis[k+1]=1,++res;
else{
if(pos!=n)S|=(1<<k),++res;
}
}else{
if(pos!=n)S|=(1<<k),++res;
else if(k!=m-1&&!vis[k+1])vis[k]=vis[k+1]=1,++res;
}
}
f[pos+1][S]=add(f[pos+1][S],f[pos][i]);
dp[pos+1][S]=add(dp[pos+1][S],mul(res,f[pos][i]));
dp[pos+1][S]=add(dp[pos+1][S],dp[pos][i]);
}
}
}
int main(){
// freopen("testdata.in","r",stdin);
freopen("bear.in","r",stdin);
freopen("bear.out","w",stdout);
scanf("%d%d%d",&n,&m,&P),lim=(1<<m);
f[1][0]=1,dp[1][0]=0;
fp(i,1,n)solve(i);
printf("%d\n",dp[n+1][0]);
}
然后我们发现复杂度高的主要原因是因为行数太多,不过列数很少,那么我们可以对列进行状压。然而这样的话会不符合推倒的顺序。
我们考虑每一条副对角线,这条副对角线上肯定是从右上到左下的推倒顺序,于是我们可以对每一条副对角线进行状压,因为副对角线上元素个数为\(min(n,m)\),所以时间复杂度没问题
信心满满的交上去结果只有\(70\)分,因为按上面那种方式枚举行的推倒情况和行的字母不太好,对于那些已经被推倒的格子,它们不管怎么选都没有影响,所以我们可以只枚举那些没有被推倒的格子,那些已经被推倒的格子直接把贡献加上去就可以了,这样的话复杂度就是\(O(3^n\times\)乱七八糟的常数\()\)
还是一句话,注意细节
//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
const int N=55,M=35,L=(1<<12)+5;
int a[N][M],f[N][L],dp[N][L],n,m,P,ans,vis[N];
int id[N][M],sz[L],bin[N];
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
void solve(int pos){
int cnt=pos-max(0,pos-n)-max(0,pos-m);
int stx,sty,edx,edy,dx,dy;
if(pos<=m)stx=pos,sty=1;
else stx=m,sty=pos-m+1;
if(pos<=n)edx=1,edy=pos;
else edx=pos-n+1,edy=n;
int qaq=pos+1>m,c=pos+1-max(0,pos+1-n)-max(0,pos+1-m);
int lim=(1<<cnt)-1;
fp(i,0,(1<<cnt)-1)if(f[pos][i]){
int T=lim^i,p=bin[sz[i]],flag=-2;
for(R int j=T;flag+=(j==T);j=(j-1)&T){
int res=0,S=0;
fp(k,0,c-1)vis[k]=0;
dx=stx,dy=sty;
fp(k,0,cnt-1){
if(!(i&(1<<k))){
if(j&(1<<k)){
if(dx!=m&&!vis[k-qaq])vis[k-qaq]=1,++res,S|=(1<<(k-qaq));
else if(dy!=n)vis[k+1-qaq]=1,++res,S|=(1<<(k-qaq+1));
}else{
if(dy!=n)vis[k+1-qaq]=1,++res,S|=(1<<(k-qaq+1));
else if(dx!=m&&!vis[k-qaq])vis[k-qaq]=1,++res,S|=(1<<(k-qaq));
}
}--dx,++dy;
}
f[pos+1][S]=add(f[pos+1][S],mul(f[pos][i],p));
dp[pos+1][S]=add(dp[pos+1][S],mul(mul(f[pos][i],res),p));
dp[pos+1][S]=add(dp[pos+1][S],mul(dp[pos][i],p));
}
}
}
int main(){
// freopen("testdata.in","r",stdin);
freopen("bear.in","r",stdin);
freopen("bear.out","w",stdout);
scanf("%d%d%d",&n,&m,&P);
fp(i,1,(1<<(min(n,m)))-1)sz[i]=sz[i>>1]+(i&1);
bin[0]=1;fp(i,1,30)bin[i]=mul(bin[i-1],2);
f[1][0]=1,dp[1][0]=0;
fp(i,1,n+m-2)solve(i);
printf("%d\n",mul(add(dp[n+m-1][0],dp[n+m-1][1]),2));
}
jzoj5990. 【北大2019冬令营模拟2019.1.6】Bear (状压dp)的更多相关文章
- [多校联考2019(Round 5 T1)] [ATCoder3912]Xor Tree(状压dp)
[多校联考2019(Round 5)] [ATCoder3912]Xor Tree(状压dp) 题面 给出一棵n个点的树,每条边有边权v,每次操作选中两个点,将这两个点之间的路径上的边权全部异或某个值 ...
- jzoj5991. 【北大2019冬令营模拟2019.1.6】Juice
题面 题解 好迷-- //minamoto #include<bits/stdc++.h> #define R register #define ll long long #define ...
- jzoj5989. 【北大2019冬令营模拟2019.1.6】Forest (set)
题面 题解 为了一点小细节卡了一个下午--我都怕我瞎用set把电脑搞炸-- 观察一次\(1\)操作会造成什么影响,比如说把\(A[i]\)从\(x\)改成\(y\): \(D[x]\)会\(-1\), ...
- jzoj5984. 【北大2019冬令营模拟2019.1.1】仙人掌 (分块)
题面 题解 数据结构做傻了.jpg 考虑每一个节点,它的儿子的取值最多只有\(O(\sqrt {m})\)种,那么可以用一个双向链表维护儿子的所有取值以及该取值的个数,那么对儿子节点修改一个值就是\( ...
- jzoj5983. 【北大2019冬令营模拟2019.1.1】多边形 (组合数学)
这其实是道打表题--你看我代码就知道了-- 咳咳来点严谨证明好了-- 前方高能请注意 首先,正多边形近似于圆,可以看做在圆里内接多边形.圆内接多边形最多只有三个锐角.因为凸多边形的外角和为\(360\ ...
- 2019.02.09 bzoj2560: 串珠子(状压dp+简单容斥)
传送门 题意简述:nnn个点的带边权无向图,定义一个图的权值是所有边的积,问所有nnn个点都连通的子图的权值之和. 思路: fif_ifi表示保证集合iii中所有点都连通其余点随意的方案数. gig ...
- 【noip模拟赛5】细菌 状压dp
[noip模拟赛5]细菌 描述 近期,农场出现了D(1<=D<=15)种细菌.John要从他的 N(1<=N<=1,000)头奶牛中尽可能多地选些产奶.但是如果选中的奶牛携 ...
- 【CSP模拟赛】Adore(状压dp 二进制)
题目描述 小w偶然间见到了一个DAG.这个DAG有m层,第一层只有一个源点,最后一层只有一个汇点,剩下的每一层都有k个节点.现在小w每次可以取反第i(1<i<n-1)层和第i+1层之间的连 ...
- [CSP-S模拟测试]:点亮(状压DP+树上背包DP)
题目传送门(内部题121) 输入格式 第一行,一个正整数$n$. 第二行,$n-1$个正整数$p_2,p_3,...,p_n$.保证$p_u$是在$1$到$u-1$中等概率随机选取的. 接下来$n$行 ...
随机推荐
- 【BZOJ2216】[Poi2011]Lightning Conductor 决策单调性
[BZOJ2216][Poi2011]Lightning Conductor Description 已知一个长度为n的序列a1,a2,...,an.对于每个1<=i<=n,找到最小的非负 ...
- 九度OJ 1140:八皇后 (八皇后问题)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:795 解决:494 题目描述: 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * ...
- Android笔记之获取显示器宽高
原先的Display.getWidth().Display.getHeight()已废弃 推荐的获取Display宽高的方法如下 DisplayMetrics metrics = new Displa ...
- Axure实现Tab选项卡切换功能
这几天用Axure画原型图的过程中,须要实现Tab选项卡切换的效果,但Axure中并没有类似于Tab控件的部件,所以能够用Axure中的动态面板(Dynamic Panel)来实现. 本文以已经汉化的 ...
- R in Action(0) 开篇
这几年数据挖掘的火热,也越来越多的人把R作为数据挖掘的一个辅助工具,据国际性组织kkguter统计有60%的人在挖掘过程中用到R工具,可见这个工具是多么的流行,对于数据统计.筛选以及画图绝对是神器.尽 ...
- Code Review 规范
CodeReview规范 CodeReivew 标准 通用原则 提交 PR 的代码必须保证自测通过 只 review 代码规范.业务逻辑,不 review 架构设计(那是写代码前应该做的事情) 干掉重 ...
- Mybatis设置sql超时时间
开始搭建项目框架的时候,忽略了sql执行超时时间的问题. 原本使用.net开发是,默认的超时时间是30s,这个时间一般一般sql是用不到的,但也不排除一些比较复杂或数据量较大的sql. 而java中, ...
- Memory Notification: Library Cache Object loaded into SGA
问题现象: 数据库服务器可以ping通,但SSH连接不了:应用.plsqldeveloper 也都连接不了.事情到了这个地步,只能重启服务器. 服务器环境:oracle10.2.0.1 +rhel5. ...
- Android Jni(Java Native Interface)笔记
首先记录一个问题,关于如何用javah生成头文件. 为什么要生成头文件?在含有 static{ System.loadLibrary("hellojni"); } 这样代码的类下面 ...
- RQNOJ魔法石之恋
魔法石之恋 (stone.pas/c/cpp) [问题描述] 在<Harry Potter and the Sorcerer's Stone>中,想得到魔法石,必须要通过许许多多的测试和游 ...