题目

  点这里看题目。

分析

  可以想到用 DP 解决。

  由于把空位放到状态里面太麻烦了,因此我们单独将 " 组 " 提出来进行 DP 。

  \(f(i,j)\):前\(i\)个人组成\(j\)个组的方案数。

  此时这个组是有顺序有编号的,并且按照编号相邻(由于在环上,\(j\) 组和 \(1\) 组也算相邻)。

  考虑三种转移:

  1.我们新建一组,并在原来的一个组后面插入新组:\(f(i+1,j+1)+=j*f(i,j)\);

  2.我们将新的人安排到新的组里面,可以放在组的两头:\(f(i+1,j)+=2j*f(i,j)\);

  3.我们用一个人将两个组合在一起,有\(j\)个组相邻:\(f(i+1,j-1)+=j*f(i,j)\);

  可以发现这样 DP 只需要保证中途状态不会超过\(G\)组即可。

  环上问题,我们可以先固定第一个人的位置,计算出方案数然后再乘上\(n\)。因此\(f(1,1)=1\)。

  现在考虑怎么再组与组之间插入空位组成结果。设现在分配\(g\)个组,第\(i\)个组后有\(x_i\)个空位,则可以得到:

\[\sum_{i=1}^g x_i=n-k\ |x_i\ge 1
\]

  这是一个可用插板法解决的问题,因此可以快速计算方案数。

  因此一般情况的答案为:

\[\sum_{i=1}^G f(k,i)\times C_{n-k-1}^{i-1}
\]

  但是如果\(n=k\),则组合数下标为\(-1\),不能算。这实际上是位置会被坐满,只有一个组的情况。当第\(k\)个人入座的时候,他只可能有一个位置可坐,因此方案数为\(n\times f(k-1,1)\)。

代码

#include <cstdio>

const int mod = 1e9 + 7;
const int MAXN = 2005; template<typename _T>
void read( _T &x )
{
x = 0;char s = getchar();int f = 1;
while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
x *= f;
} template<typename _T>
void write( _T x )
{
if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
if( 9 < x ){ write( x / 10 ); }
putchar( x % 10 + '0' );
} int f[MAXN][MAXN], C[MAXN][MAXN];
int N, K, G; void upt( int &x, const int v ) { x = ( x + v ) % mod; } void init()
{
C[0][0] = 1;
for( int i = 1 ; i <= N ; i ++ )
{
C[i][0] = C[i][i] = 1;
for( int j = 1 ; j < i ; j ++ ) C[i][j] = ( C[i - 1][j] + C[i - 1][j - 1] ) % mod;
}
} class Seatfriends
{
public:
int countseatnumb( const int n, const int k, const int g )
{
N = n, K = k, G = g;
init();
f[1][1] = 1;
for( int i = 1 ; i < K ; i ++ )
for( int j = 1 ; j <= G ; j ++ )
{
upt( f[i + 1][j], 2ll * j * f[i][j] % mod );
upt( f[i + 1][j + 1], 1ll * j * f[i][j] % mod );
if( j > 1 ) upt( f[i + 1][j - 1], 1ll * j * f[i][j] % mod );
}
int ans = 0;
if( N == K ) return 1ll * f[K - 1][1] * N % mod;
for( int i = 1 ; i <= G ; i ++ )
upt( ans, 1ll * f[K][i] * ( N == K ? 1 : C[N - K - 1][i - 1] ) % mod );
return 1ll * ans * N % mod;
}
};

[TopCoder]Seatfriends的更多相关文章

  1. TopCoder kawigiEdit插件配置

    kawigiEdit插件可以提高 TopCoder编译,提交效率,可以管理保存每次SRM的代码. kawigiEdit下载地址:http://code.google.com/p/kawigiedit/ ...

  2. 记第一次TopCoder, 练习SRM 583 div2 250

    今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...

  3. TopCoder比赛总结表

    TopCoder                        250                              500                                 ...

  4. Topcoder几例C++字符串应用

    本文写于9月初,是利用Topcoder准备应聘时的机试环节临时补习的C++的一部分内容.签约之后,没有再进行练习,此文暂告一段落. 换句话说,就是本文太监了,一直做草稿看着别扭,删掉又觉得可惜,索性发 ...

  5. TopCoder

    在TopCoder下载好luncher,网址:https://www.topcoder.com/community/competitive%20programming/ 选择launch web ar ...

  6. TopCoder SRM 596 DIV 1 250

    body { font-family: Monospaced; font-size: 12pt } pre { font-family: Monospaced; font-size: 12pt } P ...

  7. 求拓扑排序的数量,例题 topcoder srm 654 div2 500

    周赛时遇到的一道比较有意思的题目: Problem Statement      There are N rooms in Maki's new house. The rooms are number ...

  8. TopCoder SRM 590

     第一次做TC,不太习惯,各种调试,只做了一题...... Problem Statement     Fox Ciel is going to play Gomoku with her friend ...

  9. Topcoder Arena插件配置和训练指南

    一. Arena插件配置 1. 下载Arena 指针:http://community.topcoder.com/tc?module=MyHome 左边Competitions->Algorit ...

随机推荐

  1. Java中JVM相关面试题-整理

    1.JVM内存模型 •程序计数器:当前线程字所执行节码的行号指示器,用于记录正在执行的虚拟机字节指令地址,线程私有. •Java虚拟机栈:存放基本数据类型,对象的引用,方法出口等,线程私有. •本地方 ...

  2. javaScript(原型链)

    在了解javaScript的原型链之前,我们得先来看一下原型是什么. 在javaScript中,所有的函数都会有着一个特别属性:prototype(显示原型属性):当我们运行如下代码时: functi ...

  3. 王玉兰201771010128《面向对象程序设计(java)》第一周学习总结

    第一部分:课程准备部分 填写课程学习 平台注册账号: 平台名称 注册账号 博客园:www.cnblogs.com 夜空傅说 程序设计评测:https://pintia.cn/ 2326669056@q ...

  4. MySQL(6)— 事务

    六.事务 ACID: 原子性.一致性.隔离性和持久性 原子性(atomicity) :一组事务,不能再细分了,其中的sql, 要么全部提交成功,要么全部失败回滚,不能只提交其中的一部分操作. 一致性( ...

  5. Linux上,最常用的一批命令解析【10年精选】

    原文链接:https://mp.weixin.qq.com/s/QkqHexs_kOgy_5OwbwyFww 建议点击原文链接查看 不同平台linux客户端连接工具分享: windos终端神器:SSH ...

  6. 最优化之凸优化之Bregman算法

    本文介绍了Bregman迭代算法,Linearized Bregman算法(及在求解Basis Pursuit问题中的应用)和Split Bregman算法(及在求解图像TV滤波问题中的应用). 由于 ...

  7. SQL——SQL函数

    avg(col) -- 返回数值列的平均值,NULL值不包括在计算中.count(col) -- 返回指定列的值的数目,NULL不计入:count(*)返回表中记录数:count(distinct c ...

  8. Linux下搭建mongDB环境

    参考: https://blog.csdn.net/qq_35763837/article/details/79654023 https://www.linuxidc.com/Linux/2016-0 ...

  9. 05 . Python入门值循环语句

    一.Python循环语句 程序一般情况下是按照顺序执行的 编程语言提供了各种控制结构,允许更复杂的执行路径 Python中的循环语句有for和while但没有do while 循环语句允许我们执行一个 ...

  10. Rocket - debug - Example: Triggers

    https://mp.weixin.qq.com/s/zPNyrBOhsytkRrZTDTEvpw 介绍riscv-debug的使用实例:配置Triggers功能. 1. Trigger Trigge ...