题意:给你一个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)的更多相关文章

  1. hdu_5555_Immortality of Frog(状压DP)

    题目连接:hdu_5555_Immortality of Frog 题意: 给你一个NxN的网格,第N行的每一列都有个青蛙,这些青蛙只会往上走,上帝会在每个膜中放一个长生不老的药,一共有N个膜,每个膜 ...

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

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

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

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

  4. P3959 宝藏 状压dp

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 【思维题 经典模型】cf632F. Magic Matrix

    非常妙的经典模型转化啊…… You're given a matrix A of size n × n. Let's call the matrix with nonnegative elements ...

  2. 自动化运维工具——ansible命令使用(二)

    一.Ansible系列命令使用 ansible命令执行过程 1 . 加载自己的配置文件 默认/etc/ansible/ansible.cfg 2 . 加载自己对应的模块文件,如command 3 . ...

  3. vue 中有时候是数据没有同步的问题

    1,在项目中,在做表格的数据渲染的时候,表格中有input标签的数据来进行双向绑定, this.$set(this.tableTitle.money, index, money[index]+isMo ...

  4. Neon Lights in Hong Kong【香港霓虹灯】

    Neon Lights in Hong Kong Neon is to Hong Kong as red phone booths are to London and fog is to San Fr ...

  5. laravel5.2总结--响应

      1 基本响应 1.1 返回一个字符串,指定的字符串会被框架自动转换成 HTTP 响应. Route::get('/', function () { return 'Hello World'; }) ...

  6. IOS开发---菜鸟学习之路--(二)-数据获取

    第二篇了. 本篇要讲的是数据获取. 为什么将数据获取放在第二篇就讲呢? 因为我在看别人教程的时候都是先讲控件的属性,然后怎么用控件开始. 可是毕竟咱们也是有一定开发经验的人..所以很自然就想先知道怎么 ...

  7. leetcode 【 Remove Duplicates from Sorted Array II 】python 实现

    题目: Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For ex ...

  8. Leetcode 587.安装栅栏

    安装栅栏 在一个二维的花园中,有一些用 (x, y) 坐标表示的树.由于安装费用十分昂贵,你的任务是先用最短的绳子围起所有的树.只有当所有的树都被绳子包围时,花园才能围好栅栏.你需要找到正好位于栅栏边 ...

  9. STL之string使用简介

    声明一个C++字符串 string类的构造函数和析构函数如下: string s; //生成一个空字符串s string s(str) //拷贝构造函数 生成str的复制品 string s(str, ...

  10. Socket 编程中,TCP 流的结束标志与粘包问题

    因为 TCP 本身是无边界的协议,因此它并没有结束标志,也无法分包. socket和文件不一样,从文件中读,读到末尾就到达流的结尾了,所以会返回-1或null,循环结束,但是socket是连接两个主机 ...