题目

  点这里看题目。

分析

  可以想到用 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. BZOJ1022

    1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2701  Solved: 1721[Submit] ...

  2. python list 与 String 互相转换

    str0 = '127.0.0.1' list0 = str0.split('.') print(list0) #['127', '0', '0', '1'] str1 = '#'.join(list ...

  3. Git创建子分支,合并分支并提交到Gitee码云

    Git合并分支后,需要将子分支提交到git仓库,这个时候就需要单独提交子分支,其步骤如下: 先创建子分支,并包含最新当前分支下的修改数据 git checkout -b sonBranch 将新分支内 ...

  4. let面试题

    两次输出结构都是2 0 1

  5. mysql 的大文本存储TEXT & BLOB

    TEXT & BLOB 一般在保存少量字符串的时候,我们会选择 CHAR 或者 VARCHAR:而在保存较大文本时,通常会选择使用 TEXT 或者 BLOB,二者之间的主要差别是 BLOB 能 ...

  6. Java基础语法--分支结构

    if-else 结构 if(条件表达式){ 执行代码块; } if(条件表达式){ 执行代码块; }else { 执行代码块; } if(条件表达式){ 执行代码块; }else if (条件表达式) ...

  7. MySQL所有的安装部署方式

    目录 一.前言 二.关于MySQL的安装 三.部署规划 3.1 服务器规划 3.2 数据库目录规划 四.准备工具 五.通用二进制包安装MySQL 5.1 上传MySQL通用二进制安装包到node7的/ ...

  8. 函数:exit()

    函数名: exit() 所在头文件:stdlib.h(如果是"VC6.0"的话头文件为:windows.h) 功 能: 关闭所有文件,终止正在执行的进程. exit(1)表示异常退 ...

  9. [JavaWeb基础] 007.Struts2的配置和简单使用

    1.框架简介 采用Struts能开发出基于MVC(Model-View-Controller)设计模式的应用构架,用于快速开发Java Web应用.Struts实现的重点在C(Controller), ...

  10. [JavaWeb基础] 006.Struts1的配置和简单使用

    1.框架简介 采用Struts能开发出基于MVC(Model-View-Controller)设计模式的应用构架,用于快速开发Java Web应用.Struts实现的重点在C(Controller), ...