【HDOJ5555】Immortality of Frog(状压DP)
题意:给你一个NxN的网格,第N行的每一列都有个青蛙,这些青蛙只会往上走,
上帝会在每个膜中随机等概率放一个长生不老的药,
一共有N个膜,每个膜覆盖一些区间,如果这个区间恰好为N那么就是好膜,否则是坏膜,每个青蛙最多只能穿过10个坏膜,
问全部青蛙吃到药,并全部到顶层的概率*∏Ni=1(Ri−Li+1)
n<=1e3,1<=l[i]<=r[i]<=n
思路:经过思考可以发现其实就是让你求每只蛙都有且仅有配对到一个膜的方案数
From https://blog.csdn.net/bin_gege/article/details/51889815
1.我们首先统计每一列有多少个坏膜,其中一列如果大于10,那么青蛙肯定不能全部到达顶部,ans=0;
2.假设青蛙把全部的坏膜吃完了,当前的方案数为p,好膜是都可以吃的,那么此时的答案就是好膜的个数的阶乘*p。
3.这时我们就该来算全部吃完坏膜的方案数了。
4.首先每一列最多只有10个坏膜,那么我们可以用状态压缩来保存每一列坏膜的状态,记录每一列坏膜的相对位置,对于每一次转移处理出对于新的一行的状态
第一次用vector,需要注意vector从0开始编号,当vector为空时因为size是一个unsigned int,-1会出现越界的问题,所以每次都需要强制类型转换成int
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector> typedef long long ll;
using namespace std;
#define N 1100
#define oo 10000000
#define MOD 105225319 int dp[N][N],l[N],r[N],fac[N],p1[N],p2[N],n;
vector<int>c[N]; void add(int &x,int y)
{
x+=y;
if(x>=MOD) x-=MOD;
} void calc(int k)
{
for(int i=;i<=(int)c[k].size()-;i++)
{
p1[i]=-;
for(int j=;j<=(int)c[k+].size()-;j++)
if(c[k][i]==c[k+][j]){p1[i]=j; break;}
}
for(int i=;i<=(int)c[k+].size()-;i++)
{
p2[i]=-;
for(int j=;j<=(int)c[k].size()-;j++)
if(c[k+][i]==c[k][j]){p2[i]=j; break;}
}
} int turn(int x,int y)
{
int t=;
for(int i=;i<=(int)c[x].size()-;i++)
{
if(p1[i]==-)
{
if(!((y>>i)&)) return -;
}
else if(y>>i&) t|=(<<p1[i]);
}
return t;
} int main()
{
fac[]=;
for(int i=;i<N;i++) fac[i]=(ll)fac[i-]*i%MOD;
int cas;
scanf("%d",&cas);
for(int v=;v<=cas;v++)
{
scanf("%d",&n);
for(int i=;i<=n;i++) c[i].clear();
for(int i=;i<=n;i++) scanf("%d",&l[i]);
for(int i=;i<=n;i++) scanf("%d",&r[i]);
int num=;
for(int i=;i<=n;i++)
{
if(l[i]==&&r[i]==n) num++;
else
for(int j=l[i];j<=r[i];j++) c[j].push_back(i);
} int flag=,ans=;
for(int i=;i<=n;i++)
if(c[i].size()>){flag=; break;}
if(flag)
{
for(int i=;i<=n;i++)
for(int j=;j<=(<<(int)c[i].size());j++) dp[i][j]=;
dp[][]=;
for(int i=;i<=n-;i++)
{
calc(i);
for(int j=;j<=(<<(int)c[i].size())-;j++)
{
int t=turn(i,j);
if(t!=-)
{
//坏膜的数量可能比蛙少,所以可能会出现当前蛙不需要走坏膜的情况
add(dp[i+][t],dp[i][j]);
for(int k=;k<=(int)c[i+].size()-;k++)
if(p2[k]==-||!(t>>k&)) add(dp[i+][t|(<<k)],dp[i][j]);
}
}
}
ans=(ll)fac[num]*dp[n][(<<(int)c[n].size())-]%MOD;
}
printf("Case #%d: %d\n",v,ans);
}
return ;
}
【HDOJ5555】Immortality of Frog(状压DP)的更多相关文章
- hdu_5555_Immortality of Frog(状压DP)
题目连接:hdu_5555_Immortality of Frog 题意: 给你一个NxN的网格,第N行的每一列都有个青蛙,这些青蛙只会往上走,上帝会在每个膜中放一个长生不老的药,一共有N个膜,每个膜 ...
- 【状压DP】【CF8C】 Looking for Order
传送门 Description 给你n个点,每次可以从起点到最多两个点然后回到起点.求经过每个点最少一次的最短欧氏距离和是多少 Input 第一行是起点的坐标 第二行是点的个数\(n\) 下面\(n\ ...
- 【状压DP】【UVA11795】 Mega Man's Mission
传送门 Description 你要杀n个怪,每杀掉一个怪那个怪会掉落一种武器,这种武器可以杀死特定的怪.游戏初始你有一把武器,能杀死一些怪物.每次只能杀一只,求有多少种杀怪方法. Input 多组数 ...
- P3959 宝藏 状压dp
之前写了一份此题关于模拟退火的方法,现在来补充一下状压dp的方法. 其实直接在dfs中状压比较好想,而且实现也很简单,但是网上有人说这种方法是错的...并不知道哪错了,但是就不写了,找了一个正解. 正 ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- nefu1109 游戏争霸赛(状压dp)
题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...
- poj3311 TSP经典状压dp(Traveling Saleman Problem)
题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...
- [NOIP2016]愤怒的小鸟 D2 T3 状压DP
[NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...
- 【BZOJ2073】[POI2004]PRZ 状压DP
[BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...
- bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)
数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...
随机推荐
- 深入理解java虚拟机读书笔记1--java内存区域
Java在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途.创建和销毁的时间,有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁,有些则是与线程一一对应,随 ...
- django 图片上传与显示
由于图片上传的需要,学习了一波上传 1. 上传 前端代码 <form action="写上相应的定向位置" method="post" enctype=& ...
- 四 python并发编程之协程
一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...
- tp5 修改自带success或error跳转模板页面
tp5 修改自带success或error跳转模板页面 我们在使用tp5或者tp3.2的时候,用的成功或者失败跳转提示页面一般是用框架的.在后续开发过程中,根据实际项目需要,也是可以更改的,在此分享一 ...
- Android 自定义 radiobutton
<RadioButton android:id="@+id/radiobutton_pay_method" android:layout_width="30dp&q ...
- laravel5.2总结--数据迁移
迁移就像是数据库中的版本控制,它让团队能够轻松的修改跟共享应用程序的数据库结构. 1 创建一个迁移 1.1 使用artisan命令make:migration来创建一个新的迁移: ph ...
- RNNs在股票价格预测的应用
RNNs在股票价格预测的应用 前言 RNN和LSTMs在时态数据上表现特别好,这就是为什么他们在语音识别上是有效的.我们通过前25天的开高收低价格,去预测下一时刻的前收盘价.每个时间序列通过一个高斯分 ...
- IOS笔记051-手势使用
UIGestureRecognizer 利用UIGestureRecognizer,能轻松识别用户在某个view上面做的一些常见手势 UIGestureRecognizer是一个抽象类,定义了所有手势 ...
- Python 拓展之推导式
写在之前 推导式是从一个或多个迭代器快速简洁的创建数据结构的一种办法,它可以将循环和条件判断结合,从而可以避免语法冗长的代码. 列表推导式 我在之前的文章中(零基础学习 Python 之 for 循环 ...
- Halcon18 Mac os 下载
Halcon18 Mac os 下载地址:http://www.211xun.com/download_page_15.html HALCON 18 是一套机器视觉图像处理库,由一千多个算子以及底层的 ...