过河

题目描述 Description

在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,……,L(其中L是桥的长度)。坐标为0的点表示桥的起点,坐标为L的点表示桥的终点。青蛙从桥的起点开始,不停的向终点方向跳跃。一次跳跃的距离是S到T之间的任意正整数(包括S,T)。当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥。
题目给出独木桥的长度L,青蛙跳跃的距离范围S,T,桥上石子的位置。你的任务是确定青蛙要想过河,最少需要踩到的石子数。

输入描述 Input Description

输入第一行有一个正整数L(1<=L<=109),表示独木桥的长度。第二行有三个正整数S,T,M,分别表示青蛙一次跳跃的最小距离,最大距离,及桥上石子的个数,其中1<=S<=T<=10,1<=M<=100。第三行有M个不同的正整数分别表示这M个石子在数轴上的位置(数据保证桥的起点和终点处没有石子)。所有相邻的整数之间用一个空格隔开。

输出描述 Output Description

输出只包括一个整数,表示青蛙过河最少需要踩到的石子数。

样例输入 Sample Input

10
2 3 5
2 3 5 6 7

样例输出 Sample Output

2

数据范围及提示 Data Size & Hint

对于30%的数据,L<=10000;
对于全部的数据,L<=109


  考虑优化一下暴力 dp 的部分。

定理 如果正整数 $a, b$ 满足 $a > 1$ 或者 $b > 1$,且 $(a, b) = 1$,那么 $ax + by (x \geqslant 0, y \geqslant 0)$ 不能表示出的最小自然数是 $ab - a - b$

  证明 首先考虑证明不存在 $x, y$ 使得 $ax + by = ab - a - b$。假设存在整数 $x, y$。

  那么有 $a(x + 1) + b(y + 1) = ab$。

  所以 $a \mid b(a + y + 1)$,所以 $a \mid (y + 1)$。同理可得 $b | (x + 1)$。

  因为 $x \geqslant 0, y \geqslant 0, ab > 0$,所以 $a(x + 1) + b(y + 1) \geqslant ab + ab = 2ab > ab$,矛盾。

  然后证明对于任意自然数 $c > ab - a - b$ 都能表示出来。根据裴蜀定理有,存在整数$x_0, y_0$,使得 $a(x_0 + kb) + b(y_0 - ka) = d$,如果 $x_0 \geqslant 0, y_0 \geqslant 0$ 那么找到了一组合法的解,如果 $x_0 <0, y_0 < 0$ 显然不可能,否则 $x_0 < 0$ 或 $y_0 < 0$,不妨设 $x_0 \geqslant 0, y_0 < 0$,如果 $x_0 \geqslant b$,那么令 $x_0' = x_0 - b, y_0' = y_b + a$ ,所以只用考虑当 $0 \leqslant x_0 < b, y_0 < 0$ 的情况,此时有 $a \cdot x_0 + b\cdot y_0 \leqslant ab - a - b$,这和 $a \cdot x_0 + b\cdot y_0 = c > ab - a - b$ 矛盾。

  如果 $T > S$,那么至少包含 $x$ 和 $x + 1$,因为 $(x, x + 1) = 1$,所以对于长度大于 $x(x + 1) - x - x - 1 < 100$ 的长度可以直接看成 100,因为它们总能走到。

  如果 $T = S$,可以简单处理掉。

Code

 #include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
typedef bool boolean;
#define INF 0xfffffff
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b) ifstream fin("river.in");
ofstream fout("river.out"); int M, L;
int l, r;
int* d;
int* s;
int* f; inline void init() {
fin >> L;
fin >> l >> r >> M;
d = new int[(const int)(M + )];
for(int i = ; i <= M; i++)
fin >> d[i];
sort(d + , d + M + );
} inline void solve() {
if(l == r) {
int res = ;
for(int i = ; i <= M; i++) {
if(d[i] % l == )
res++;
}
fout << res;
return;
}
s = new int[(const int)(M * + )];
memset(s, , sizeof(int) * (M * + ));
d[] = ;
int newd = ;
for(int i = ; i <= M; i++) {
if(d[i] - d[i - ] > )
newd += ;
else newd += d[i] - d[i - ];
s[newd]++;
}
f = new int[(const int)(newd + + r)];
memset(f, 0x3f, sizeof(int) * (newd + + r));
f[] = ;
for(int i = ; i <= newd; i++) {
if(f[i] > M) continue;
for(int j = l; j <= r; j++)
smin(f[i + j], f[i] + s[i + j]);
}
int res = M;
for(int i = newd; i <= newd + r; i++)
if(f[i] >= )
smin(res, f[i]);
fout << res;
} int main() {
init();
solve();
return ;
}

题目描述 Description

  佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”。在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会。一共有n个同学,编号从1到n。一开始,同学们按照1,2,……,n的顺序坐成一圈,而实际上每个人都有两个最希望相邻的同学。如何下命令调整同学的次序,形成新的一个圈,使之符合同学们的意愿,成为摆在佳佳面前的一大难题。
佳佳可向同学们下达命令,每一个命令的形式如下:
(b1,b2,...bm-1,bm)
  这里m的值是由佳佳决定的,每次命令m的值都可以不同。这个命令的作用是移动编号是b1,b2,…… bm –1,bm的这m个同学的位置。要求b1换到b2的位置上,b2换到b3的位置上,……,要求bm换到b1的位置上。
  执行每个命令都需要一些代价。我们假定如果一个命令要移动m个人的位置,那么这个命令的代价就是m。我们需要佳佳用最少的总代价实现同学们的意愿,你能帮助佳佳吗?

输入描述 Input Description

输入第一行是一个整数n(3<=n<=50000),表示一共有n个同学。其后n行每行包括两个不同的正整数,以一个空格隔开,分别表示编号是1的同学最希望相邻的两个同学的编号,编号是2的同学最希望相邻的两个同学的编号,……,编号是n的同学最希望相邻的两个同学的编号。

输出描述 Output Description

这一行只包含一个整数,为最小的总代价。如果无论怎么调整都不能符合每个同学的愿望,则输出-1。

样例输入 Sample Input

4
3 4
4 3
1 2
1 2

样例输出 Sample Output

2

数据范围及提示 Data Size & Hint

【数据规模】
对于30%的数据,n<=1000;
对于全部的数据,n<=50000。


  因为这是一个环,所以可以剖环成链,因为剖开点不一样,就会导致结果不一样,所以正着反着每个地方都去剖一次。

  接下来是考虑如何快速地求解需要付出的代价。这个代价等于所有在它不该在的位置的数量。

  这个结论可以这么来说明,对于一个在它不该在的位置的i,那么必定存在它占掉另一个的位置且另一个占掉了它的位置,当按照这个关系连接起来就等于一个环,刚好可以按照题目中的变换方式(旋转这个环),把环上的数变到它应该在的位置。

  但是这么做仍然会超时,所以得继续考虑优化。对于改变剖开点的位置,我们规定每次改变把剖开点向前挪动一次,那么我们可以记录每个位置上的数,离它第一次回到自己正确位置上需要挪动剖开点多少次,然后就找个最大值,然后用n一减就可以出结果。

  注意判断是否可以满足所有需求。主要的原因是:a希望坐在b,c旁边,但是b,c中有人不是最希望坐在a的旁边。

Code

 #include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
typedef bool boolean;
#define INF 0xfffffff
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b) template<typename T>class Matrix{
public:
T *p;
int lines;
int rows;
Matrix():p(NULL){ }
Matrix(int rows, int lines):lines(lines), rows(rows){
p = new T[(lines * rows)];
}
T* operator [](int pos){
return (p + pos * lines);
}
};
#define matset(m, i, s) memset((m).p, (i), (s) * (m).lines * (m).rows) ifstream fin("fire.in");
ofstream fout("fire.out"); int n;
Matrix<int> sit;
int* exist; inline void init() {
fin >> n;
sit = Matrix<int>(n + , );
exist = new int[(const int)(n + )];
memset(exist, , sizeof(int) * (n + ));
for(int i = ; i <= n; i++) {
fin >> sit[i][] >> sit[i][];
for(int j = ; j < ; j++) {
exist[sit[i][j]]++;
if(exist[sit[i][j]] > || sit[i][j] == i) {
fout << "-1";
exit();
}
}
}
for(int i = , c; i <= n; i++) {
for(int j = ; j < ; j++) {
c = sit[i][j];
if(sit[c][] != i && sit[c][] != i) {
fout << "-1";
exit();
}
}
}
} int myabs(int x) { return (x < ) ? (x + n) : (x); } int* list;
int* round; int calc(int x) {
list[] = ;
list[] = sit[][x];
int last = list[];
memset(round, , sizeof(int) * (n + ));
round[]++, round[myabs( - last)]++;
int ret = max(round[], round[myabs( - last)]);
for(int i = , j; i <= n; i++) {
if(sit[last][] == list[i - ])
list[i] = sit[last][];
else list[i] = sit[last][];
last = list[i];
j = myabs(i - last);
round[j]++;
smax(ret, round[j]);
}
return ret;
} int res = INF;
inline void solve() {
list = new int[(const int)(n + )];
round = new int[(const int)(n + )];
for(int i = , a; i < ; i++) {
a = calc(i);
smin(res, n - a);
}
fout << res;
} int main() {
init();
solve();
return ;
}

小测(noip2005的两道题) 2017.3.3的更多相关文章

  1. 上午小测3 T1 括号序列 && luogu P5658 [CSP/S 2019 D1T2] 括号树 题解

    前 言: 一直很想写这道括号树..毕竟是在去年折磨了我4个小时的题.... 上午小测3 T1 括号序列 前言: 原来这题是个dp啊...这几天出了好几道dp,我都没看出来,我竟然折磨菜. 考试的时候先 ...

  2. 小测几种python web server的性能

    http://blog.csdn.net/raptor/article/details/8038476 因为换了nginx就不再使用mod_wsgi来跑web.py应用了,现在用的是gevent-ws ...

  3. 福州大学软件工程1816 | W班 第8次作业[团队作业,随堂小测——校友录]

    作业链接 团队作业,随堂小测--校友录 评分细则 本次个人项目分数由两部分组成(博客分满分40分+程序得分满分60分) 博客和程序得分表 评分统计图 千帆竞发图 总结 旅法师:实现了更新,导出,查询, ...

  4. 朱晔和你聊Spring系列S1E11:小测Spring Cloud Kubernetes @ 阿里云K8S

    有关Spring Cloud Kubernates(以下简称SCK)详见https://github.com/spring-cloud/spring-cloud-kubernetes,在本文中我们主要 ...

  5. 随堂小测APP使用体验

    随堂小测APP使用体验 先要去注册账号需要填写用户名.密码.手机号.学号/教师号.学校.专业.即可注册,注册成功后,即可登录APP进,登陆进去以后.会有两个界面,课堂和我的,注册.登录简单,通俗易懂, ...

  6. C++ 性能小测 1 二维数组的遍历效率

    C++ 性能小测 1 二维数组的遍历效率 遍历二维数组时,常规思路是使用一个嵌套循环.一方面,由于 CPU 使用了分支预测技术,因此通常将循环次数最多循环的放在最内层.另一方面,由于二维数组是按行存储 ...

  7. 小qyvlik 先看两个视频,和 QtQuick UI 问答

    http://edu.csdn.net/course/detail/1042 http://edu.csdn.net/course/detail/335 http://blog.csdn.net/qy ...

  8. [福大软工] Z班 团队作业——随堂小测(同学录) 作业成绩

    团队作业--随堂小测(同学录) 作业链接 http://www.cnblogs.com/easteast/p/7763645.html 作业情况 本次作业从原先预计的3小时,有些组打了鸡血连续肝了4. ...

  9. MySQL课堂小测

    目录 一.基本知识与操作方法 二.小测具体内容 (一)向数据库表中添加记录 (二)下载并导入world.sql (三)数据库查询与输出 (四)查询数据库并求某字段和 (五)查询数据库并取最大& ...

随机推荐

  1. SET NAMES

    High Performance MySQL, Third Editionby Baron Schwartz, Peter Zaitsev, and Vadim Tkachenko Settings ...

  2. Json模块dumps、loads、dump、load函数介绍

    转自:http://blog.csdn.net/mr_evanchen/article/details/77879967 Json模块dumps.loads.dump.load函数介绍 1.json. ...

  3. 数据库bcp导入导出批处理工具

    应公司策划要求,需要一个数据库按表导入导出的工具配合svn来进行差异匹配,方便策划每天对数据库修改的记录工具,我使用bcp命令实现如下批处理工具,中间踩了不少坑,现保存在这边希望可以帮到需要此工具的同 ...

  4. Django ORM之QuerySet

    Django ORM用到三个类:Manager.QuerySet.Model.Manager定义表级方法(表级方法就是影响一条或多条记录的方法),我们可以以models.Manager为父类,定义自己 ...

  5. kubernetes实战(十一):k8s使用openLDAP统一认证

    1.基本概念 为了方便管理和集成jenkins,k8s.harbor.jenkins均使用openLDAP统一认证. 2.部署openLDAP 此处将openLDAP部署在k8s上,openLDAP可 ...

  6. linux中vim常用命令

    vim工作模式 vi 文件名 进入命令模式 i a o 进入插入模式 ESC键 回到命令模式 : 进入编辑模式 添加行号 :set number/nu :wq 保存退出 插入命令 a 在光标所在字符后 ...

  7. UIAlertview 添加图片

    - (void)willPresentAlertView:(UIAlertView *)alertView { 在这个方法中, 绘制需要的东西 uiview *myView = [uiview all ...

  8. POJ3087:Shuffle'm Up(模拟)

    http://poj.org/problem?id=3087 Description A common pastime for poker players at a poker table is to ...

  9. 菜刀php过waf

    关于PHP 一.waf为啥会拦截菜刀.菜刀在连接时,会向server端POST数据,抓包查看: 会看到他向server端post了 @eval(base64_decode($_POST[z0]));  ...

  10. windows上备份mysql数据库

    方案一:采用mysql自带的工具mysqldump. 脚本文件backup.bat如下: set  "YMD=%date:~,4%%date:~5,2%%date:~8,2%"cd ...