BZOJ 2699: 更新 (DP)
题目
对于一个数列A[1…N],一种寻找最大值的方法是:依次枚举A[2]到A[N],如果A[i]比当前的A[1]值要大,那么就令A[1]=A[i],最后A[1]为所求最大值。假设所有数都在范围[1, K]内,按上面的步骤执行,有多少个长度N的数列满足A[1]被更新的次数恰好为P呢?
N,P<=150,K<=300
题解
感觉数据组数有点多,其实可以直接预处理出所有答案。
定义f[i][j][k]f[i][j][k]f[i][j][k]表示长度为iii,用≤j\le j≤j的数,形成的被更新kkk次的数列方案数。
这里把第一个数出现也看作更新了一次。
分类转移:
- jjj第一次出现,方案为:f[i−1][j−1][k−1]f[i-1][j-1][k-1]f[i−1][j−1][k−1]
- 放1→j1\to j1→j中任意值,方案为:j⋅(f[i−1][j][k]−f[i−1][j−1][k])j\cdot(f[i-1][j][k]-f[i-1][j-1][k])j⋅(f[i−1][j][k]−f[i−1][j−1][k]),这里前缀和相减,是需要之前的最大值恰好为jjj,这样才能不重不漏。
- 再加上没有用到最大值jjj的方案:f[i][j−1][k]f[i][j-1][k]f[i][j−1][k],也就是做个前缀和。
CODE
#include <bits/stdc++.h>
using namespace std;
char cb[1<<18],*cs,*ct;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<18,stdin),cs==ct)?0:*cs++)
inline void rd(int &x) {
x = 0; char ch; while(!isdigit(ch=getc()));
do x=x*10+ch-'0'; while(isdigit(ch=getc()));
}
const int mod = 1e9 + 7;
const int MAXN = 150;
const int MAXM = 300;
int n, k, p, f[MAXN+5][MAXM+5][MAXN+5];
int main () {
for(int i = 0; i <= MAXM; ++i) f[0][i][0] = 1;
for(int i = 1; i <= MAXN; ++i)
for(int j = 1; j <= MAXM; ++j)
for(int k = 1; k <= MAXN; ++k)
f[i][j][k] = (f[i-1][j-1][k-1] + 1ll*j*(f[i-1][j][k]-f[i-1][j-1][k]+mod)%mod + f[i][j-1][k]) % mod;
int T; rd(T); while(T--) rd(n), rd(k), rd(p), printf("%d\n", f[n][k][p+1]);
}
BZOJ 2699: 更新 (DP)的更多相关文章
- BZOJ.2655.calc(DP/容斥 拉格朗日插值)
BZOJ 洛谷 待补.刚刚政治会考完来把它补上了2333.考数学去了. DP: 首先把无序化成有序,选严格递增的数,最后乘个\(n!\). 然后容易想到令\(f_{i,j}\)表示到第\(i\)个数, ...
- 【bzoj2699】更新 dp
题目描述 对于一个数列A[1..N],一种寻找最大值的方法是:依次枚举A[2]到A[N],如果A[i]比当前的A[1]值要大,那么就令A[1]=A[i],最后A[1]为所求最大值.假设所有数都在范围[ ...
- bzoj 1597 斜率DP
1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5115 Solved: 1897[Submit] ...
- ZOJ 3632 Watermelon Full of Water (线段树 区间更新 + dp)
题目大意: 让每天都能吃到西瓜. 最少须要花多少钱. 思路分析: dp[pos] 就表示 要让 前i天每天都有西瓜吃.最少须要花多少钱. 那么假设你买这个西瓜的话. 那么这个西瓜能吃的持续时间都要更 ...
- BZOJ 4033 树形DP
http://blog.csdn.net/mirrorgray/article/details/51123741 安利队长blog- 树形dp吧,状态挺显然的,dp[x][j]表示以x为根的子树中,选 ...
- BZOJ 1090 - 区间dp
Magic Door 题目大意: 给一个字符串,可以将重复的串缩成x(a),表示x个a,求能缩成的最小长度. 题目分析 区间dp: dp[i][j]表示i~j处理后的最小长度, 则有 \[dp[i][ ...
- 持续更新——dp的一些技巧
共菜鸡笔者看的--会慢慢更新,也请看到的大佬留意一眼,指出不足. 对于一些对部分点的二维\(dp\),状态从左上角继承而来时,对于一个点\((x,y)\),对它编号\(x*m+y\),按照这个顺序\( ...
- BZOJ 3270 && BZOJ 1778 (期望DP && 高斯消元)
BZOJ 3270 :设置状态为Id(x,y)表示一人在x,一人在y这个状态的概率. 所以总共有n^2种状态. p[i]表示留在该点的概率,Out[i]=(1-p[i])/Degree[i]表示离开该 ...
- BZOJ 1040 树形DP+环套树
就是有n个点n条边,那么有且只有一个环那么用Dfs把在环上的两个点找到.然后拆开,从这条个点分别作树形Dp即可. #include <cstdio> #include <cstrin ...
随机推荐
- [转帖]Hive学习之路 (一)Hive初识
Hive学习之路 (一)Hive初识 https://www.cnblogs.com/qingyunzong/p/8707885.html 讨论QQ:1586558083 目录 Hive 简介 什么是 ...
- java当中JDBC当中请给出一个SQLServer DataSource and SingleTon例子
[学习笔记] 5.SQLServer DataSource and SingleTon: import net.sourceforge.jtds.jdbcx.*;import java.sql.*;i ...
- 从零开始学Flask框架-008
数据库 安装Flask-SQLAlchemy扩展库 pip install flask-sqlalchemy 引入SQLAlchemy类 from flask_sqlalchemy import SQ ...
- Linux 内核错误码
#define EPERM 1 /* Operation not permitted */#define ENOENT 2 /* No such ...
- C#插入时间
//获取日期+时间 DateTime.Now.ToString(); // 2008-9-4 20:02:10 DateTime.Now.ToLocalTime().ToString(); // 20 ...
- CentOS && Ubuntu 环境下 Docker 的安装配置
CentOS 7 install Docker Docker 支持的 centos 版本:CentOS 6.5(64-bit)或更高的版本 使用 yum 安装 1)确保 yum 包更新到最新 [roo ...
- 洛谷P3372--线段树代码模板1
如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格 ...
- EntityFramework进阶(一)- DbContext与ObjectContext互转
本系列原创博客代码已在EntityFramework6.0.0测试通过,转载请标明出处 EF中我们常用的是DbContext作为上下文,如果要想获取元数据等信息还是要用到ObjectContext这个 ...
- Java 之 字节输出流[OutputStream]
一.字节输出流 java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地. 该类中定义了字节输出流的基本共性功能方法. 公性方法: public v ...
- FreeRTOS 移植
添加FreeRTOS源码到工程中 在工程源码中创建FreeRTOS目录存放拷贝的文件 拷贝FreeRTOS->Source中的文件 可将其他不需要的文件夹全部删掉,只留3个 拷贝Demo中Fre ...