codeforces 425E
题意:对于[l1, r1], [l2, r2]...[lm, rm]线段组成的一个集合S,我们定义f(S)为最大的不相交(没有任何公共点)线段数,现在给定n及k,n表示线段范围,即任何[li, ri]有1<=li<=ri<=n,求有多少个集合使得f(S) = k。
思路:刚看到题目感觉不会,也就不多想。。
突然问了下小胖,小胖说他做过,不难。。然后我就慢慢想了。。
仔细想想,确实不难。。
假设现在已经给定了一个S,那么我们怎么求f(S)?
很显然,我们可以贪心,按照r排序,那么我们每次只要取最小r的线段,删除覆盖的,依次做完最后取到的线段肯定最多。。
这么以来对于任意一个集合S,我们肯定可以用最小的有用线段的右端点r来表示其状态。。
所以用f[i][j]表示最后一个有用线段右端点为i,最长有j段不相交的线段的方案数
则递推到f[k][j+1](k>i)的状态有:
在【i+1, k】区间内一定选了至少一条以k为右端点的线段,选法2k-i - 1
左端点在【1, i】右端点【i+1, k】的线段可以任意选不影响f值,有2(k-i)*i种
所以 f[k][j+1] += f[i][j] *(2k-i - 1) * 2(k-i)*i
code:
#include <bits/stdc++.h>
#define M0(x) memset(x, 0, sizeof(x))
#define M 1000000007
using namespace std;
typedef long long ll;
const int maxn = ;
int n, m;
ll dp[][], p[]; void solve(){
if (m == ){
puts("");
return;
}
M0(dp);
dp[][] = ;
p[] = ;
for (int i = ; i <= n * n; ++i) p[i] = (p[i-] << ) % M;
ll tmp;
int c = ;
for (int i = ; i < n; ++i)
for (int j = ; j < m; ++j) if (dp[i][j]){
c = ;
for (int k = i+; k <= n; ++k){
c += i;
tmp = dp[i][j] * (p[(k - i)]-) % M * p[c] % M;
dp[k][j+] = (dp[k][j+] + tmp) % M;
}
}
ll ans = ;
for (int i = ; i <= n; ++i){
tmp = p[(n-i) * i] * dp[i][m] % M;
ans = (ans + tmp) % M;
// printf("%d : %lld\n",i, ans);
}
cout << ans << endl;
} int main(){
freopen("a.in", "r", stdin);
while (scanf("%d%d", &n, &m) != EOF){
solve();
}
return ;
}
codeforces 425E的更多相关文章
- CodeForces 425E Sereja and Sets
意甲冠军: 集S它包括了很多间隔[l,r] 和1<=l<=r<=n f(S)个不相交的区间 问给出n和f(S) 有几种可能的S集合 思路: dp好题 至于为啥是dp- 我 ...
- Codeforces 425E Sereja and Sets dp
Sereja and Sets 我们先考虑对于一堆线段我们怎么求最大的不相交的线段数量. 我们先按 r 排序, 然后能选就选. 所以我们能想到我们用$dp[ i ][ j ]$表示已经选了 i 个线段 ...
- CodeForces - 425E Sereja and Sets 题解
题目大意: 我们有一个集合 S,其中包含了 m 个不完全相同的区间[l1,r1],[l2,r2]…[lm,rm] (1≤li≤ri≤n,li,ri 都为整数). 定义 f(S)=k,表示集合 S 中能 ...
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
- 【Codeforces 738C】Road to Cinema
http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...
- 【Codeforces 738A】Interview with Oleg
http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...
- CodeForces - 662A Gambling Nim
http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...
- CodeForces - 274B Zero Tree
http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...
随机推荐
- python函数递归和生成器
一.什么是递归 如果函数包含了对其自身的调用,该函数就是递归的.递归做为一种算法在程序设计语言中广泛应用,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的 ...
- go中方法的接收者是值或者指针的区别
值类型的变量和指针类型的变量 先声明一个结构体: type T struct { Name string } func (t T) M1() { t.Name = "name1" ...
- sqoop1.99.6 update导出语句
我们采用sqoop-export插入数据的时候,如果主键已经存在了,插入会失败.想要根据主键判断是否要进行insert操作还是update操作,sqoop提供了update语法.示例 sqoop -- ...
- Ninject的使用
摘要 DI容器的一个责任是管理他创建的对象的生命周期.他应该决定什么时候创建一个给定类型的对象,什么时候使用已经存在的对象.他还需要在对象不需要的时候处理对象.Ninject在不同的情况下管理对象的生 ...
- delphi 10 seattle 安卓服务开发(二)
关于delphi 10 移动服务开发的几张图
- VC++绘图时,利用双缓冲解决屏幕闪烁 转载
最近做中国象棋,绘制界面时遇到些问题,绘图过程中屏幕闪烁,估计都会想到利用双缓冲来解决问题,但查了下网上双缓冲的资料,发现基本是MFC的,转化为VC++后,大概代码如下: void DrawBmp(H ...
- POJ 1113 - Wall 凸包
此题为凸包问题模板题,题目中所给点均为整点,考虑到数据范围问题求norm()时先转换成double了,把norm()那句改成<vector>压栈即可求得凸包. 初次提交被坑得很惨,在GDB ...
- to_char 详解
对TO_CHAR的讨论可以分为从两种类型的数据到字符的转换:DATE和NUMBER. TO_CHAR函数返回VARCHAR2数据类型的值. 1. NUMBER TO CHAR 语法: TO_CHAR( ...
- VS调试在Win7(vista系列)操作系统下 HttpListener拒绝访问解决办法
一. VS调试在Win7(vista系列)操作系统下 HttpListener无法绑定多个 指定IP.端口问题 来自:http://www.cnblogs.com/ryhan/p/4195693.ht ...
- ADT bundle和Eclipse和Android Studio有什么区别?安卓开发该用哪个?
这三个版本的出现有一定的历史的原因:1.最开始只有eclipse+独立的adt一种开发环境,但是由于eclipe作为一种通用的ide,带来的问题太多,经常出现eclipse的版本不兼容adt的情况,或 ...