题目大意:

  我们有一个集合 S,其中包含了 m 个不完全相同的区间[l1,r1],[l2,r2]…[lm,rm] (1≤li≤ri≤n,li,ri 都为整数)。

  定义 f(S)=k,表示集合 S 中能取出最多 k 个区间,使得这 k 个区间两两不相交。 问当 f(S)=k 时,符合条件的集合 S 有多少个。

思路:

  f[i][j]表示集合S中所有区间的端点均小于等于i且f(S)=j的集合S的个数。

  显然i≥j,则f[i][j]由f[k][j-1](j-1≤k≤i)转移而来,新的与之前区间不相交的区间的起点为k+1,k+1≤终点≤i,则有2i-k-1种选择出有且仅有一个区间与之前的区间不相交即有用区间(k+1为起点,有i-k个与之前的区间不相交,任取其中的多个或一个),而多出的无用区间即与之前的相交的区间的两个端点一个小于等于k一个大于k,则有(i-k)*k个,任取,有2(i-k)*k种,所以转移方程为f[i][j]=∑(f[k][j-1]*(2i-k-1)*2(i-k)*k)。

代码:

 #include<cstdio>
#define mo 1000000007
long long mi[],f[][];
int i,j,k,n,m; int main()
{
scanf("%d%d",&n,&m),k=n*n>>;
for (mi[]=i=;i<k+;++i)
if ((mi[i]=mi[i-]<<)>=mo) mi[i]-=mo;
for (i=;i<=n;++i) f[i][]=;
for (i=;i<=n;++i)
for (j=;j<=i;++j)
for (k=j-;k<=i;++k)
f[i][j]=(f[i][j]+f[k][j-]*(mi[i-k]-)%mo*mi[(i-k)*k])%mo;
printf("%lld\n",f[n][m]);
return ;
}

最新文章

  1. 兼容好的JS图片上传预览代码
  2. swift之inout
  3. 更新记录后关闭子窗口并刷新父窗口的Javascript
  4. Headroom.js – 快速响应用户的页面滚动操作
  5. 浅谈malloc()与free()
  6. A840S黑砖修复过程(2013-05-22修改)
  7. Java Web程序工作原理
  8. ubuntu下安装Vmare Workstation,并安装mac补丁
  9. WPF-19:分享一个样式(左右滑动选中的checbox)
  10. [转]Libev源码分析 -- 整体设计
  11. Bash变量扩展修改符
  12. 如何在已安装Python条件下,安装Anaconda,,并将原有Python添加到Anaconda中
  13. js数组排序,支持正反排序以及多维度排序
  14. asp.net mvc 简单项目框架的搭建过程(一)对Bll层和Dal层进行充分解耦
  15. CentOS下MySQL的安装
  16. CF786B Legacy(线段树优化建图)
  17. Physics Experiment 弹性碰撞 [POJ3684]
  18. PKCS RSA执行标准
  19. java web复习(二)
  20. Java static 语句块

热门文章

  1. 数论+DP HDOJ 4345 Permutation
  2. time模块,datetime模块
  3. Windows 7操作系统下PHP 7的安装与配置(图文详解)
  4. JS格式化工具(转)
  5. JDK集合框架--综述
  6. 原生开发之css样式问题(持续更新)
  7. lua使用lfs.dll库进行文件操作
  8. NOT IN、NOT EXISTS的相关子查询改用LEFT JOIN--sql2000性能优化
  9. F. Asya And Kittens并查集
  10. php 阿里云短信验证码