cf 559C 考虑到黑色的格子很少,那么我把(1,1)变成黑色,然后按每个黑色格子接近终点的程度排序,计算黑色格子不经过另一个黑色格子到达终点的方案,对于当前的格子,要减去在它右下角的所有方案数(注意不是f值)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=1e9+;
LL MOD(LL x){return (x%mod+mod)%mod;} LL jc[],inv[];
LL quick_pow(LL A,LL p)
{
LL ret=;
while(p!=)
{
if(p%==)ret=(ret*A)%mod;
A=(A*A)%mod;p/=;
}
return ret;
}
LL getC(int n,int m){return jc[m]*inv[m-n]%mod*inv[n]%mod;} struct node{int x,y;}a[];
bool cmp(node n1,node n2){return n1.x+n1.y>n2.x+n2.y;}
LL f[];
int main()
{
jc[]=,inv[]=;for(int i=;i<=;i++)jc[i]=(jc[i-]*i)%mod,inv[i]=quick_pow(jc[i],mod-);
int n,m,K;
scanf("%d%d%d",&n,&m,&K);
for(int i=;i<=K;i++)
scanf("%d%d",&a[i].x,&a[i].y);
a[++K].x=,a[K].y=;
sort(a+,a+K+,cmp); for(int i=;i<=K;i++)
{
f[i]=getC(n-a[i].x,(n+m)-(a[i].x+a[i].y));
for(int j=;j<i;j++)
if(a[i].x<=a[j].x&&a[i].y<=a[j].y)
{
f[i]=MOD( f[i]-MOD(f[j]*getC(a[j].x-a[i].x,(a[j].x+a[j].y)-(a[i].x+a[i].y))) );
}
}
printf("%I64d\n",f[K]);
return ;
}

cf 559C

poj1737 口胡一波题解,我们知道n个点的无向图个数有2^(n*(n-1)/2)个,那么就去算不联通的,假设存在有一个包括点1的块大小为k,剩下的就是n-k个点的无向图个数了。

poj1037 其实可以借鉴一下康托展开的思想的。。。对于当前位应该选取最大的那个剩下位方案数少于m的,那么方案数就要用DP维护了。设f[i][j][k]表示枚举到第几位,选的是当前排第j的,是高位还是低位。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
LL f[][][]; void initf()
{
f[][][]=f[][][]=;
for(int i=;i<=;i++)
for(int j=;j<=i;j++)
{
for(int k=j;k<=i-;k++)f[i][j][]+=f[i-][k][];
for(int k=;k<=j-;k++)f[i][j][]+=f[i-][k][];
}
} bool v[];
int main()
{
initf(); int T;
scanf("%d",&T);
while(T--)
{
int n;LL m;
scanf("%d%lld",&n,&m);
memset(v,false,sizeof(v));
int x,k;
for(int j=;j<=n;j++)
{
if(f[n][j][]>=m){x=j,k=;break;}
else m-=f[n][j][]; if(f[n][j][]>=m){x=j,k=;break;}
else m-=f[n][j][];
}
v[x]=true;printf("%d",x);
for(int i=;i<=n;i++)
{
k^=; int j=;
for(int y=;y<=n;y++)
{
if(v[y]==true)continue;
j++; if((k==&&y<x)||(k==&&y>x))
{
if(f[n-i+][j][k]>=m){x=y;break;}
else m-=f[n-i+][j][k];
}
}
v[x]=true;printf(" %d",x);
}
printf("\n");
}
return ;
}

poj1037

0x5C 计数类DP的更多相关文章

  1. 动态规划——区间DP,计数类DP,数位统计DP

    本博客部分内容参考:<算法竞赛进阶指南> 一.区间DP 划重点: 以前所学过的线性DP一般从初始状态开始,沿着阶段的扩张向某个方向递推,直至计算出目标状态. 区间DP也属于线性DP的一种, ...

  2. SDOI2010代码拍卖会 (计数类DP)

    P2481 SDOI2010代码拍卖会 $ solution: $ 这道题调了好久好久,久到都要放弃了.洛谷的第五个点是真的强,简简单单一个1,调了快4个小时! 这道题第一眼怎么都是数位DP,奈何数据 ...

  3. CH5E26 扑克牌 (计数类DP)

    $ CH~5E26~\times ~ $ 扑克牌: (计数类DP) $ solution: $ 唉,计数类DP总是这么有套路,就是想不到. 这道题我们首先可以发现牌的花色没有价值,只需要知道每种牌有 ...

  4. $Poj1737\ Connected\ Graph$ 计数类$DP$

    AcWing Description 求$N$个节点的无向连通图有多少个,节点有标号,编号为$1~N$. $1<=N<=50$ Sol 在计数类$DP$中,通常要把一个问题划分成若干个子问 ...

  5. $CF559C\ Gerald\ and\ Fiant\ Chess$ 计数类$DP$

    AcWing Description 有个$H$行$W$列的棋盘,里面有$N$个黑色格子,求一个棋子由左上方格子走到右下方格子且不经过黑色格子的方案数. $1<=H,M<=1e5,1< ...

  6. $CH5302$ 金字塔 区间$DP$/计数类$DP$

    CH Sol f[l][r]表示l到r这段区间对应的金字塔结构种数 发现是f[l][r]是可以由比它小的区间推出来的 比如已知f[l+1][k],f[k+1][r],不难想到f[l][r]+=f[l+ ...

  7. hackerrank【Lego Blocks】:计数类dp

    题目大意: 修一个层数为n,长度为m的墙,每一层可以由长度为1.2.3.4的砖块构成. 每一层都在同一个长度处出现缝隙是方案非法的,问合法的方案数有多少种 思路: 先求出总方案,再减去所有非法的方案数 ...

  8. codeforces 277.5 div2 F:组合计数类dp

    题目大意: 求一个 n*n的 (0,1)矩阵,每行每列都只有两个1 的方案数 且该矩阵的前m行已知 分析: 这个题跟牡丹江区域赛的D题有些类似,都是有关矩阵的行列的覆盖问题 牡丹江D是求概率,这个题是 ...

  9. Codeforces 9D How many trees? 【计数类DP】

    Codeforces 9D How many trees? LINK 题目大意就是给你一个n和一个h 问你有多少个n个节点高度不小于h的二叉树 n和h的范围都很小 感觉有无限可能 考虑一下一个很显然的 ...

随机推荐

  1. 涉及spring的相关概念

    1.pojo 2.为了降低java开发的复杂性,spring采用了4中策略 (1).基于POJO的轻量级和最小侵入性编程 (2).通过依赖注入和接口编程实现松耦合 (3).基于切面和惯例进行声明式编程 ...

  2. c++中sin,cos,arcsin等和在C/C++中使用pi (π) 值

    先 #include<math.h> 反3角函数有 acos(double),asin(double),atan(double),atan(double,double),返回值 doubl ...

  3. day1笔记 初识python,paython基础

    一.计算机,操作系统 软件发送指令给操作系统,操作系统再把指令发送给  内存,cpu,硬盘等 二.Python的历史. Python2: 1.臃肿,源码的重复量很多.2.语法不清晰,掺杂着c,++,P ...

  4. Tomcat虚拟目录

    x先来看一段server.xml文件里的配置: <Host appBase="" autoDeploy="true" debug="0" ...

  5. JS原生追加子节点

    var fragment = document.createDocumentFragment(); li = document.createElement('li'); li.className = ...

  6. java编程:将数组的第一个为最大第二个为最小以此类推

    import java.util.Scanner; public class Max_Min { public static void main(String[] args) { int[] a = ...

  7. hdu2587(递推)

    目前做过的最纠结的一道递推题. 情况比较多,比较复杂... 这题最主要的还是要推出当m=2 时和m>2时,用什么方法最优. 给个数据 n=3,m=2   需要48 n=3,m=3 需要81 如果 ...

  8. 初识Python、数据类型、基本语句

    Python是一种面向对象的.直译式计算机程序设计语言,也是一种功能强大的且完善的通用型语言,是一种脚本语言. Python的主要特点:是面向过程的.面向对象的:模块丰富,功能强大:语法简单易学:扩展 ...

  9. 如何避免升级 Linux 实例内核后无法启动

    如何避免升级 Linux 实例内核后无法启动_系统配置_操作运维 Linux_常见问题_云服务器 ECS-阿里云 https://help.aliyun.com/knowledge_detail/59 ...

  10. bootstrap页面布局

    首先,我们必须明确,在这四种角色登录网站,看到页面是不同,这里不仅涉及到后端的权限控制,还涉及到前端页面的布局,区分好这些角色看的东西哪些是相同的,哪些又是不同的呢,这个必须在这里想明白,所以要做好页 ...