题目连接:hdu_5555_Immortality of Frog

题意:

给你一个NxN的网格,第N行的每一列都有个青蛙,这些青蛙只会往上走,上帝会在每个膜中放一个长生不老的药,一共有N个膜,每个膜覆盖一些区间,如果这个区间恰好为N那么就是好膜,否则是坏膜,每个青蛙最多只能穿过10个坏膜,问全部青蛙吃到药,并全部到顶层的分配方案。

题解:

1.我们首先统计每一列有多少个坏膜,其中一列如果大于10,那么青蛙肯定不能全部到达顶部,ans=0;

2.假设青蛙把全部的坏膜吃完了,当前的方案数为p,好膜是都可以吃的,那么此时的答案就是好膜的个数的阶乘*p。

3.这时我们就该来算全部吃完坏膜的方案数了。

4.首先每一列最多只有10个坏膜,那么我们可以用状态压缩来保存每一列坏膜的状态,但这个状态只是这一列的相对位置,比如这一列第10行的坏膜的相对位置为1,第24行的坏膜相对位置为2

5.我们dp[i][j]表示第i列的坏膜相对位置的吃掉情况,那么我们要转移到i+1列,就要转移第i列已经吃过的坏膜的情况到第i+1列,因为j表示的是当前列的坏膜相对位置,我们要对应找到i+1列的坏膜的相对位置,列如:第i列有 第12,15,18,20是坏膜,第i+1列有第15,20,30,40是坏膜,假设第i列的第15行坏膜已经吃掉,第15行在第i列的相对位置为2,此时我们要转移到i+1列上,对应的就是第i+1列的15行,第15行在i+1列的相对位置为1,这样就是dp[i][1<<(2-1)]转移到了dp[i+1][1<<(1-1)]。

6.到最后我们取的是最后一列的全部坏膜吃掉的情况,这里就包含了所有坏膜吃完的情况,然后乘上好膜的阶乘即可


 #include<cstdio>
#include<vector>
#define F(i,a,b) for(int i=a;i<=b;i++)
typedef long long LL;
using namespace std; const int N=,mod=;
int dp[N][N],n,l[N],r[N],good,jie[N],p1[],p2[];
vector<int>g[N]; void init(){
jie[]=;
F(i,,)jie[i]=(LL)jie[i-]*i%mod;
} void del(int x){
F(i,,(int)g[x].size()-){
p1[i]=-;
F(j,,(int)g[x+].size()-)
if(g[x][i]==g[x+][j]){p1[i]=j;break;}
}
F(i,,(int)g[x+].size()-){
p2[i]=-;
F(j,,(int)g[x].size()-)
if(g[x+][i]==g[x][j]){p2[i]=j;break;}
}
} inline int new_s(int x,int y){
int ans=;
F(i,,(int)g[x].size()-){
if(p1[i]==-){if(!((y>>i)&))return -;}
else if(y>>i&)ans|=(<<p1[i]);
}//这个坏膜在当前列的编号对应下一列的编号
return ans;
} inline void up(int &x,int y){x+=y,x=x>mod?x-mod:x;} int main(){
init();
int t;scanf("%d",&t);
F(ic,,t){
scanf("%d",&n),good=;
F(i,,n)scanf("%d",l+i),g[i].clear();
F(i,,n)scanf("%d",r+i);
F(i,,n)if(l[i]==&&r[i]==n)good++;
else F(j,l[i],r[i])g[j].push_back(i);
int flag=,ans=;//坏膜大于10,无法分配
F(i,,n)if(g[i].size()>){flag=;break;}
if(!flag){
F(i,,n){//dp初始化
int sz=g[i].size();
F(j,,(<<sz))dp[i][j]=;
}
dp[][]=;
F(i,,n-){
del(i);
F(j,,(<<(int)g[i].size())-){
int now=new_s(i,j);
if(now!=-){//将上一列已经吃过的坏膜转移到这列对应的状态
up(dp[i+][now],dp[i][j]);
F(k,,(int)g[i+].size()-)//如果上一列没有这个坏膜或者有但没吃,那么这一列肯定吃掉这个膜
if(p2[k]==-||!(now>>k&))
up(dp[i+][now|(<<k)],dp[i][j]);
}
}
}
ans=(LL)jie[good]*dp[n][(<<(int)g[n].size())-]%mod;
}
printf("Case #%d: %d\n",ic,ans);
}
return ;
}

hdu_5555_Immortality of Frog(状压DP)的更多相关文章

  1. 【状压DP】【CF8C】 Looking for Order

    传送门 Description 给你n个点,每次可以从起点到最多两个点然后回到起点.求经过每个点最少一次的最短欧氏距离和是多少 Input 第一行是起点的坐标 第二行是点的个数\(n\) 下面\(n\ ...

  2. 【状压DP】【UVA11795】 Mega Man's Mission

    传送门 Description 你要杀n个怪,每杀掉一个怪那个怪会掉落一种武器,这种武器可以杀死特定的怪.游戏初始你有一把武器,能杀死一些怪物.每次只能杀一只,求有多少种杀怪方法. Input 多组数 ...

  3. P3959 宝藏 状压dp

    之前写了一份此题关于模拟退火的方法,现在来补充一下状压dp的方法. 其实直接在dfs中状压比较好想,而且实现也很简单,但是网上有人说这种方法是错的...并不知道哪错了,但是就不写了,找了一个正解. 正 ...

  4. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  5. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

  6. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

  7. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

  8. 【BZOJ2073】[POI2004]PRZ 状压DP

    [BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...

  9. bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)

    数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...

随机推荐

  1. List泛型集合常用方法

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace List ...

  2. ORACLE小工具:存储过程清空所有表或使所有触发器失效

    清空所有表: CREATE OR REPLACE PROCEDURE CLEAN_TABLES as v_tablename varchar2(256); cursor cur_tablename i ...

  3. oracle导入导出数据库

    oracle导出dmp文件: 开始->运行->输入cmd->输入 exp user/password@IP地址:1521/数据库实例 file=文件所在目录 (如:exp user/ ...

  4. 《Think in UML》读后感

  5. JavaScript(6)——事件1.0

    ---恢复内容开始--- 事件 好不容易回到正轨,好好学习,天天向上.今天写的是事件,感觉内容蛮多的,所以分了两篇写,主要写了事件流.事件处理程序.事件对象.恩,明天还会再有一篇,哈哈哈.我努力的!我 ...

  6. hadoop 及hbase zookeeper 经常出现问题

    往往是以下几个 1/ 各节点时间不统一(写shell文件统一时间) 2/配置文件 /etc/hosts文件中ip地址配置错误(更新ip) 3/断网后重启机器 ip地址被修改(更新配置文件中的ip)

  7. Flask -- 入门

    安装virtualenv 作用:可以为一个项目单独提供一份Python的安装,安全  pip install virtualenv 使用virtualenv为MyProject项目安装Python,并 ...

  8. android 线程池的使用

    转自http://www.trinea.cn/android/java-android-thread-pool/ Java(Android)线程池 介绍new Thread的弊端及Java四种线程池的 ...

  9. CodeForces 754C Vladik and chat (DP+暴力)

    题意:给定n个人的m个对话,问能不能找一个方式使得满足,上下楼层人名不同,并且自己不提及自己. 析:首先预处理每一层能有多少个user可选,dp[i][j] 表示第 i 层是不是可以选第 j 个use ...

  10. AC Me

    AC Me Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submiss ...