[noip模拟题]排队
【问题描述】
小sin所在的班有n名同学,正准备排成一列纵队,但他们不想按身高从矮到高排,那样太单调,太没个性。他们希望恰好有k对同学是高的在前,矮的在后,其余都是矮的在前,高的在后。如当n=5,k=3时,假设5人从矮到高分别标为1、2、3、4、5,则(1,5,2,3,4)、(2,3,1,5,4)、(3,1,4,2,5)都是可行的排法。小sin想知道总共有多少种可行排法。
【输入】
输入文件名为lineup.in。
一行两个整数n和k,意义见问题描述。
【输出】
输出文件名为lineup.out。
输出一个整数,表示可行排法数。由于结果可能很大,请输出排法数mod 1799999的值。
【输入输出样例】
|
lineup.in |
lineup.out |
|
5 3 |
15 |
【数据范围】
对于20%的数据,有n≤10,k≤40;
对于60%的数据,有n≤100,k≤500;
对于100%的数据,有n≤100,k≤n*(n-1)/2。
这道题并不是特别地难,其实只需要这样分析,假设把第i个同学加入前面(i-1)个同学组成的有j‘组逆序对的队列中(假设加入的同学的大小从低到高)
,这时i同学插在最后面不会增加逆序对的个数,但是插在第k(从后往前数)位同学前面会增加k个逆序对(第i个同学身高最高),如下:
原队列: 1 4 2 3
将第5个同学插入第2(k = 3)位同学前: 1 5 4 2 3
上面褐色就是和这个数产生的逆序对的个数。
那么达到一个状态(i,j)就是第(i- 1)个人组成的队列所有能够通过插入第i个同学得到的j个逆序对
这么说也存在不可能的时候
比如原队列: 1 2 3
插入进去后要使逆序对的数量增加到4个,要使增加的逆序对的个数最大,即将第4位同学增加到队首,增加3个逆序对,0 + 3 < 4
所以这种情况是不可能的
于是还要满足这个条件(假设之前这个逆序对的个数为k) k + i - 1 > j
得到了这个递推式(f的初值为0)(如果下表为负也不用管)
f[i][j] = f[i - ][j] + f[i - ][j - ] +...+ f[i - ][j - i + ]
貌似这样的时间复杂度是O(kn2)对于100这样的范围还是可以过的
不过明明是可以再继续优化,就只用个前缀和就可以轻松代替第三重循环,也可以化简一下上面的递推式
,总之有很多方法可以消去第三重循环
Code
#include<iostream>
#include<fstream>
#define moder 1799999
using namespace std;
ifstream fin("lineup.in");
ofstream fout("lineup.out");
int f[][];
long long s[][];
int n,k;
int buf;
void init_dp(){
for(int i = ;i <= n;i++){
f[i][] = ;
s[i][] = ;
}
}
void dp(){
f[][] = ;
s[][] = s[][] + ;
for(int i = ;i <= n;i++){
buf = (i - )*(i - )/;
for(int j = ;j < i ;j++){
f[i][j] = s[i - ][min(j,buf)];
s[i][j] = (s[i][j - ] + f[i][j]) % moder;
}
for(int j = i ;j <=i*(i - )/;j++){
f[i][j] = (s[i - ][min(buf,j)] - s[i - ][j - i] + moder) % moder;
s[i][j] = (s[i][j - ] + f[i][j]) % moder;
}
}
}
int main(){
fin>>n>>k;
init_dp();
dp();
fout<<f[n][k];
return ;
}
[noip模拟题]排队的更多相关文章
- 【入门OJ】2003: [Noip模拟题]寻找羔羊
这里可以复制样例: 样例输入: agnusbgnus 样例输出: 6 这里是链接:[入门OJ]2003: [Noip模拟题]寻找羔羊 这里是题解: 题目是求子串个数,且要求简单去重. 对于一个例子(a ...
- NOIP模拟题汇总(加厚版)
\(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...
- 9.9 NOIP模拟题
9.9 NOIP模拟题 T1 两个圆的面积求并 /* 计算圆的面积并 多个圆要用辛普森积分解决 这里只有两个,模拟计算就好 两圆相交时,面积并等于中间两个扇形面积减去两个三角形面积 余弦定理求角度,算 ...
- 8.22 NOIP 模拟题
8.22 NOIP 模拟题 编译命令 g++ -o * *.cpp gcc -o * *.c fpc *.pas 编译器版本 g++/gcc fpc 评测环境 位 Linux, .3GHZ CPU ...
- NOIP模拟题17.9.26
B 君的任务(task)[题目描述]与君初相识,犹如故人归.B 君看到了Z 君的第一题,觉得很难.于是自己出了一个简单题.你需要完成n 个任务,第i 任务有2 个属性ai; bi.其中ai 是完成这个 ...
- noip模拟题题解集
最近做模拟题看到一些好的题及题解. 升格思想: 核电站问题 一个核电站有N个放核物质的坑,坑排列在一条直线上.如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质. 任务:对于给定 ...
- NOIP 模拟题
目录 T1 : grid T2 : ling T3 : threebody 数据可私信我. T1 : grid 题目:在一个\(n*n\)的方格中,你只能斜着走.为了让问题更简单,你还有一次上下左右走 ...
- 9.22 NOIP模拟题
吉林省信息学奥赛 2017 冬令营 ...
- 6.19 noip模拟题(题目及解析转自 hzwer 2014-3-15 NOIP模拟赛)
Problem 1 高级打字机(type.cpp/c/pas) [题目描述] 早苗入手了最新的高级打字机.最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧. 请为这种高级打字机设计一个程序 ...
随机推荐
- linux:echo命令示例
echo命令:用于字符串的输出 $echo string 1.打印普通字符串 $echo "hello kumata" hello kumata #这里的双引号完全可以省略,以下 ...
- 设计模式之——flyweight模式
flyweight模式,又叫做享元模式. 顾名思义,享元模式就是共享一个元素. 百度百科 解释为: 享元模式(英语:Flyweight Pattern)是一种软件设计模式.它使用共享物件,用来尽可能减 ...
- web window pixel等笔记
原文:http://www.w3cplus.com/css/viewports.html 屏幕尺寸 Screen size =显示器尺寸 screen.width 和 screen.height.这两 ...
- Java并发包中CyclicBarrier的源码分析和使用
CyclicBarrier的介绍和源码分析 CyclicBarrier的字母意思是可循环(Cyclic)使用的屏障(Barrier).它要做的事情是,让一组线程到达一个屏障(也可以叫做同步点)时被阻塞 ...
- auto类型-现代C++新特性
auto类型 C++11中引入的auto主要用于类型推导.auto在C++98中"存储类型指示符"的语义,由于使用极少且多余,该语义从C++11开始被删除. auto类型推导用于从 ...
- 用Python实现的数据结构与算法:开篇
一.概述 用Python实现的数据结构与算法 涵盖了常用的数据结构与算法(全部由Python语言实现),是 Problem Solving with Algorithms and Data Struc ...
- edgeR使用学习【转载】
转自:http://yangl.net/2016/09/27/edger_usage/ 1.Quick start 2. 利用edgeR分析RNA-seq鉴别差异表达基因: #加载软件包 librar ...
- [LeetCode] 476. Number Complement_Easy tag: Bit Manipulation
这个题目思路就是比如101 的结果是010, 可以从111^101 来得到, 那么我们就需要知道刚好比101多一位的1000, 所以利用 while i <= num : i <<= ...
- Windows多线程基础
进程与线程基础 程序: 计算机指令的集合,以文件的形式存储在磁盘上 进程: 正在运行是程序实例,以是一个程序在其自身的地址空间的一次执行活动.进程有一个进程管理的内核对象和地址空间组成. 线程: 程序 ...
- Java接口多线程并发测试 (二)
原文地址http://www.cnblogs.com/yezhenhan/archive/2012/01/09/2317636.html 这是一篇很不错的文章,感谢原博主的分享! JAVA多线程实现和 ...