题目连接: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. 当用反射获取一个model,这个model里面字段有nullable的时候,获取字段真实类型

    Using Reflection to Determine whether an Type is Nullable And Get the underlying Type /// <summar ...

  2. mysql多表链接查询

    select area from areas where cityid=(select cityid from cities where city like '杭州%') and id!=(selec ...

  3. 解决curl中errno为51和60的错误

    今天使用curl调用https接口的时候,发现接收不了数据 然后打印出curl_errno和curl_error发现是60错误,而生产环境是51错误 查了相关资料 加上两个参数就可以了 curl_se ...

  4. 对http协议断点续传的理解

    断点续传指的是下载传输文件可以中断,之后重新下载时可以接着中断的地方开始下载,而不必从头开始下载.断点续传需要客户端和服务端都支持. 原理是客户端一块一块的请求数据,最后将下载回来的数据块拼接成完整的 ...

  5. VirtualBox中安装CentOS(新手教程)

    1.VirtualBox下载 官网:http://www.virtualbox.org/wiki/Downloads 下载好之后,一路下一步安装即可 2.CentOS下载 官网:https://www ...

  6. bash color

    紫色:300A24 黄色:C4A000 Tango 紫色: 200213

  7. java中list集合的内容,如何使用像数据库中group by形式那样排序

    java中list集合的内容,如何使用像数据库中group by形式那样排序,比如:有一个 List<JavaBean> 他中包含了一些如下的内容JavaBean:name    mone ...

  8. 初识Iaas,paas

    Iaas(Infrastructure-as-a-service),直译为基础设备作为一种服务. Paas(Platform as a service),直译为平台作为一种服务. 暂且忘掉这两个单词, ...

  9. 数据库NULL和 ‘’ 区别

    NULL判断时 : IS NOT NULL ''判断时: !=''

  10. Qt Quick里的图形效果:阴影(Drop Shadow)

    Qt Quick提供了两种阴影效果: DropShow,阴影.这个元素会根据源图像,产生一个彩色的.模糊的新图像,把这个新图像放在源图像后面,给人一种源图像从背景上凸出来的效果. InnerShado ...