一定要注意Topcoder的提交机制

Links: 原题地址 Vjudge

Solution

这道题思维比较巧妙。 一看就基本知道是一个Dp题。

首先转换一下,用列而不是行来设第一维的状态,因为每列只有放或不放两种状态。行的受力情况很复杂,这里啊

那么对于每一列,到了要分配Left的时候我们再把前面的列分配过来。

Right的时候,我们就反其道而行之,把Right贮存下来,然后之后每一个格子都考虑要不要分配一次。

这样Dp状态就显而易见:\(Dp[i][j][k]\)表示前i列中有j列空余kRight没有处理的方案数。

然后就比较容易写出dp方程.下面是废话:

先分类。这一列可以对Left Right造成影响. 也可以不造成影响(放在没用的地方或完全不让放)

因为Left,Right对状态影响很大,所以分成两个式子。

notice:在考虑问题的时候中间问题的中间态如果不是很重要的话,整体都可以略过

具体见代码

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define clar(a, b) memset((a), (b), sizeof(a))
#define debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef long double LD;
int read() {
char ch = getchar();
int x = 0, flag = 1;
for (;!isdigit(ch); ch = getchar()) if (ch == '-') flag *= -1;
for (;isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
return x * flag;
}
void write(int x) {
if (x < 0) putchar('-'), x = -x;
if (x >= 10) write(x / 10);
putchar(x % 10 + 48);
} const int Maxn = 59, Maxm = 209, Mod = 1e9 + 7;
class TaroCheckers {
public:
LL C[Maxm * 10][Maxm * 10], dp[Maxm][Maxm][Maxn], fac[Maxm * 10];
LL L[Maxm], R[Maxm];
void calcMath(LL m) {
C[0][0] = fac[0] = 1;
rep (i, 1, m) fac[i] = fac[i - 1] * i % Mod;
rep (i, 1, m) {
C[i][0] = C[i][i] = 1;
rep (j, 1, i - 1) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % Mod;
}
}
int getNumber(vector <int> Left, vector <int> Right, int m) {
LL n = (LL)Left.size();
calcMath(n + m); clar(dp, 0); clar(L, 0), clar(R, 0);
rep (i, 0, n - 1) ++L[Left[i]], ++R[m - Right[i] + 1];
dp[0][0][0] = 1; LL res = 0;
rep (i, 0, m - 1) {
LL cnt1 = L[i + 1], cnt2 = R[i + 1];
rep (j, 0, i)
rep (k, 0, n)
if (dp[i][j][k]) {
if (j + 1 >= cnt1) (dp[i + 1][j + 1 - cnt1][k + cnt2] += dp[i][j][k] * C[j + 1][cnt1] % Mod * fac[cnt1] % Mod) %= Mod;
if (j >= cnt1) (dp[i + 1][j - cnt1][k + cnt2] += dp[i][j][k] * C[j][cnt1] % Mod * fac[cnt1] * (res - cnt2 + 1) % Mod) %= Mod;
if (j >= cnt1 && k + cnt2 - 1 >= 0) (dp[i + 1][j - cnt1][k + cnt2 - 1] += dp[i][j][k] * C[j][cnt1] % Mod * fac[cnt1] % Mod * (k + cnt2) % Mod) %= Mod;
}
res += cnt1 - cnt2;
} return dp[m][0][0];
}
};

[SRM613~] TaroCheckers的更多相关文章

随机推荐

  1. Android系统改动时间格式为24小时制

    1. frameworks/base/packages/SettingsProvider/res/values/defaults.xml 添加<stringname="time_12_ ...

  2. VC++中的int main(int argc, char argv[])是什么意思

    这是C/C++的一重要函数,叫主函数.无论程序多复杂,代码中必须有这么一个函数,也只能有一个这样的函数:程序执行时就是从这个函数进入的.由于问得比较笼统,如果你想知道详细情况的话,发给你一个网友的求助 ...

  3. 高端技巧:怎样使用#define定义变量

    Introduction 想在源文件里定义一个跟行号有关的变量,每次都手动输入实在是太慢了.本文介绍怎样使用宏定义来定义与行号有关的变量. 比如:我们想在源码的第10行定义A_10这种一个整形变量. ...

  4. nyoj473 A^B Problem (高速幂)

    题目473 题目信息 执行结果 pid=473" style="text-decoration:none; color:rgb(55,119,188)">本题排行 ...

  5. Android 常用Shell命令

    1.查询模拟器/设备实例 adb devices 2.从模拟器/设备中拷入或拷出文件(默认拷贝在执行目录) 从模拟器或者设备中复制文件或目录,使用(如下命): adb pull <remote& ...

  6. 2016/3/1 淘宝 腾讯 网易 css初始化代码 以及最基础的初始化

    淘宝官网(http://www.taobao.com/)样式初始化 body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, o ...

  7. Codeforces 755 F. PolandBall and Gifts 多重背包+贪心

    F. PolandBall and Gifts   It's Christmas time! PolandBall and his friends will be giving themselves ...

  8. Google Gson使用简介

    1.Google Gson在android studio的使用 gradle:compile 'com.google.code.gson:gson:2.2.4' 2.Gson 注解 @Expose 注 ...

  9. ibatis和mybatis的区别

    区别1:全局配置文件(sqlMapConfig.xml)的差异 主要是元素标签命名的差异,比如mybatis的根元素标签为<configuration>,ibatis的 根元素标签为< ...

  10. i节点,容易被人遗忘的节点

    部分内容转自点击打开链接 点击打开链接 前段时间做了RHCE的一道题,是iSCSi的,后来在挂载的时候说是磁盘被占用.当时资料找了很多结果还是没有找到解决方法.反倒是发现了这个inode,也是关于被占 ...