这题还挺对胃口的哈哈~是喜欢的画风!回家路上一边听歌一边想到的解法,写出来记录一下……

 首先,由于 \(b_{k} < a_{k + 1}\) ,所以我们可以看作是在一个长度为 n 的序列上选择出 k 个不相交的区间使得这 k个区间的长度各不相同。那么我们可以先求出 \(f[i][j]\) 表示选择了 \(i\) 个区间,这 \(i\) 个区间的区间长度总和为 \(j\) 的方案数。然后,我们考虑用这些方案数与序列剩下的长度的划分的方案数共同构成答案。所以我们再求一个 \(g[i][j]\) 表示将 \(j\) 的长度划分成可空的 \(i\) 段的方案数。答案 \(h[k][n]\) 表示在长为 n 的序列上选出了 \(k\) 个不相交,各不相同的区间的方案数。有了 \(f,g\)数组,我们只需要枚举一下选择的区间总长 i,将 \(f[k][i] * g[k + 2][n - i]\) 加到答案中即可。

  但是,这样做不是 \(1000^{3}\) 的的吗?实际上,k 的取值范围远不可能到达 1000。由于区间的长度各不相同,我们不难求出当 \(k >= 45\) 的时候答案为 0,并不需要计算。这样,我们就可以在优秀的 \(5e7\) 的复杂度下通过此题~

#include <bits/stdc++.h>
using namespace std;
#define maxn 1010
#define maxm 100000
#define maxk 50
#define mod 1000000007
#define int long long
int N = , lim = , h[maxn][maxn];
int t[][maxk][maxn], f[maxk][maxn], g[maxk][maxn];
int fac[maxm], inv[maxm]; int read()
{
int x = , k = ;
char c; c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} int C(int n, int m)
{
if(n < m || n < || m < ) return ;
return fac[n] * inv[m] % mod * inv[n - m] % mod;
} void pre()
{
fac[] = ; inv[] = inv[] = ;
for(int i = ; i < maxm; i ++) fac[i] = fac[i - ] * i % mod;
for(int i = ; i < maxm; i ++) inv[i] = (mod - mod / i) * inv[mod % i] % mod;
for(int i = ; i < maxm; i ++) inv[i] = inv[i - ] * inv[i] % mod;
} void Up(int &x, int y) { x = x + y; if(x >= mod) x -= mod; }
void Work()
{
int pre = , now = ; t[pre][][] = ;
for(int i = ; i <= N; i ++)
{
memset(t[now], , sizeof(t[now]));
for(int k = ; k <= lim; k ++)
for(int j = ; j <= N; j ++)
{
t[now][k][j] = t[pre][k][j];
if(k && j - i >= ) Up(t[now][k][j], t[pre][k - ][j - i]);
}
swap(pre, now);
}
for(int i = ; i <= lim; i ++)
for(int j = ; j <= N; j ++)
f[i][j] = t[pre][i][j] * fac[i] % mod;
for(int i = ; i <= lim; i ++) g[i][] = ;
for(int i = ; i <= lim; i ++)
for(int j = ; j <= N; j ++)
g[i][j] = C(i + j - , j); for(int i = ; i <= lim; i ++)
for(int j = ; j < N; j ++)
{
int ret = ;
for(int k = ; k <= j; k ++)
Up(ret, f[i][k] * g[i + ][j - k] % mod);
h[i][j] = ret;
}
} signed main()
{
pre(); Work(); int T = read();
while(T --)
{
int n = read(), K = read();
if(K <= lim) printf("%I64d\n", h[K][n]);
else printf("0\n");
}
return ;
}

【题解】CF#403 D-Beautiful Pairs of Numbers的更多相关文章

  1. CF 403D Beautiful Pairs of Numbers

    The sequence of integer pairs (a1, b1), (a2, b2), ..., (ak, bk) is beautiful, if the following state ...

  2. [CF403D]Beautiful Pairs of Numbers

    题意:给定$n,k$,对于整数对序列$\left(a_1,b_1\right),\cdots,\left(a_k,b_k\right)$,如果$1\leq a_1\leq b_1\lt a_2\leq ...

  3. Codeforces 403D: Beautiful Pairs of Numbers(DP)

    题意:转换模型之后,就是1~n个数中选k个,放到一个容量为n的背包中,这个背包还特别神奇,相同的物品摆放的位置不同时,算不同的放法(想象背包空间就是一个长度为n的数组,然后容量为1的物体放一个格子,容 ...

  4. cf 403 D

    D. Beautiful Pairs of Numbers time limit per test 3 seconds memory limit per test 256 megabytes inpu ...

  5. CF 55 D. Beautiful numbers

    D. Beautiful numbers 链接 题意: 求[L,R]中多少个数字可以整除它们的每一位上的数字. 分析: 要求模一些数字等于0等价于模它们的lcm等于0,所以可以记录当前出现的数字的lc ...

  6. Codeforces CF#628 Education 8 D. Magic Numbers

    D. Magic Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  7. 竞赛题解 - CF Round #524 Div.2

    CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...

  8. 题解——CF Manthan, Codefest 18 (rated, Div. 1 + Div. 2) T5(思维)

    还是dfs? 好像自己写的有锅 过不去 看了题解修改了才过qwq #include <cstdio> #include <algorithm> #include <cst ...

  9. 【题解】 Codeforces 919F A Game With Numbers(拓扑排序+博弈论+哈希)

    懒得复制,戳我戳我 Solution: 我感觉我也说不太好,看Awson的题解吧. 说一点之前打错的地方: 连边存的是hash后的数组下标 if(ans[ num( C[a.hash()] , C[b ...

随机推荐

  1. ORB-SLAM(十)LoopClosing Sim3求解

    主要参考这篇论文 Horn B K P. Closed-form solution of absolute orientation using unit quaternions[J]. JOSA A, ...

  2. 三 Hive 数据处理 自定义函数UDF和Transform

    三  Hive 自定义函数UDF和Transform 开篇提示: 快速链接beeline的方式: ./beeline -u jdbc:hive2://hadoop1:10000 -n hadoop 1 ...

  3. Docker - 常用命令集

    启动容器 docker run -d -p 58080:8080 -p 58000:8000 --name mytomcat1.0 -v /root/webapps/:/opt/apache-tomc ...

  4. VDI数据恢复

    环境:cirtix xendesktop 问题:VDI无法正常启动,后台登录查看报错.多次重启无效果,客户部分数据存放在启动盘. 解决方法:1.创建一台新的VDI(必须保证关机)2.将原有VDI启动盘 ...

  5. 「专题训练」k-Tree(CodeForces Round #247 Div.2 C)

    题意与分析(Codeforces-431C) 题意是这样的:给出K-Tree--一个无限增长的树,它的每个结点都恰有\(K\)个孩子,每个节点到它\(K\)个孩子的\(K\)条边的权重各为\(1,2, ...

  6. hdu1789 Doing Homework again(贪心+排序)

    Doing Homework again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  7. hdu1394Minimum Inversion Number(线段树,求最小逆序数)

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  8. centos下php环境安装redis

    一.安装redis(仅可在服务器使用,尚不能通过浏览器访问) (1)首先下载redis:wget http://download.redis.io/releases/redis-4.0.9.tar.g ...

  9. 初学Direct X(8) ——碰撞检测

    初学Direct X(8) --碰撞检测 真正让一个游戏鹤立鸡群的是程序对碰撞的响应有多好,这里介绍两种检测的方法: 1) 基于边框的碰撞检测 2) 基于距离的碰撞检测 1. 基于边框的碰撞检测 1. ...

  10. .NET中发送邮件的实现

    .NET中发送邮件 注意: 1.引用下列命名空间: using System.Net; using System.Net.Mail; 2.确保你使用的发送邮件的邮箱开启了stamp服务等. /// & ...