[SRM613~] TaroCheckers
一定要注意Topcoder的提交机制
Solution
这道题思维比较巧妙。 一看就基本知道是一个Dp题。
首先转换一下,用列而不是行来设第一维的状态,因为每列只有放或不放两种状态。行的受力情况很复杂,这里啊
那么对于每一列,到了要分配Left的时候我们再把前面的列分配过来。
到Right的时候,我们就反其道而行之,把Right贮存下来,然后之后每一个格子都考虑要不要分配一次。
这样Dp状态就显而易见:\(Dp[i][j][k]\)表示前i列中有j列空余k个Right没有处理的方案数。
然后就比较容易写出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的更多相关文章
随机推荐
- Callable线程
写一个Callable线程 import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; im ...
- centos mysql错误信息处理
mysql_secure_installation 提示错误:Enter current password for root (enter for none):ERROR 1045 (28000): ...
- 简单JS全选、反选代码
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org ...
- php事务操作示例
<?php //数据库连接 $conn = mysql_connect('localhost', 'root', '');mysql_select_db('test', $conn); /* 支 ...
- Codeforces Round #316 (Div. 2) C. Replacement
题意:给定一个字符串,里面有各种小写字母和' . ' ,无论是什么字母,都是一样的,假设遇到' . . ' ,就要合并成一个' .',有m个询问,每次都在字符串某个位置上将原来的字符改成题目给的字符, ...
- Android自带的分享功能案例
MainActivity的代码 package com.hpsvse.weiboshare; import java.io.File; import android.net.Uri; import a ...
- RabbitMQ通过shovel插件迁移数据
前言 生产环境中会遇到RabbitMQ数据迁移的场景,例如:切换云服务厂商.不同Region之间数据迁移.新搭建RabbitMQ实例,数据需要同步至新的RabbitMQ实例. 前提条件: 源Rabbi ...
- 深入分析JavaWeb Item13 -- jsp指令具体解释
一.JSP指令简单介绍 JSP指令(directive)是为JSP引擎而设计的.它们并不直接产生不论什么可见输出,而仅仅是告诉引擎怎样处理JSP页面中的其余部分. 在JSP 2.0规范中共定义了三个指 ...
- 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) E.Passwords AC自动机+dp
题目链接:点这里 题意: 让你构造一个长度范围在[A,B]之间 字符串(大小写字母,数字),问你有多少种方案 需要满足条件一下: 1:构成串中至少包含一个数字,一个大写字母,一个小写字母: 2:不 ...
- 在 Vim 中优雅地查找和替换 vi【转】
本文转载自:http://harttle.land/2016/08/08/vim-search-in-file.html 总有人问我 Vim 中能不能查找,当然能!而且是超级强的查找! 这篇文章来详细 ...