noip2015提高组day2解题报告
1、跳石头
题目描述
一年一度的“跳石头”比赛又要开始了!
这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。
为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走 M块岩石(不能移走起点和终点的岩石)。
输入格式
输入文件第一行包含三个整数 L,N,M,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会至多移走的岩石数。保证 L≥1 且 N≥M≥0。
接下来 N行,每行一个整数,第 i 行的整数 Di(0<Di<L), 表示第 i 块岩石与起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个岩石出现在同一个位置。
输出格式
输出文件只包含一个整数,即最短跳跃距离的最大值。
样例一
input
25 5 2 2 11 14 17 21
output
4
explanation
将与起点距离为 2和 14 的两个岩石移走后,最短的跳跃距离为 4(从与起点距离 17 的岩石跳到距离 21 的岩石,或者从距离 21 的岩石跳到终点)。
限制与约定
测试点编号 | n,m的规模 | L的规模 |
---|---|---|
1 | n,m≤10 |
L≤10^9 |
2 | ||
3 | n,m≤100 |
|
4 | ||
5 | ||
6 | n,m≤50000 |
|
7 | ||
8 | ||
9 | ||
10 |
时间限制:1s
空间限制:128MB
/*
显然,二分答案
*/
#include<cstdio> #include<iostream> using namespace std; int l,n,m; int a[50005]; int L; int check(int x) { int last = 0;//last为前一个石头到指向石头的距离 int ans = 0; for(int i=1;i<=n;i++) { if(a[i]-last<x) //如果第i个石头到前一个石头的距离小于假设的答案 ans++; //该石头可以搬走 else//如果大于(即满足条件) last = a[i]; //则保留该石头,并将last赋值为该石头到原点的距离以便计算下一个石头到它的距离 } if(ans>m)return 0; return 1; } int main() { scanf("%d%d%d",&L,&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); a[n+1]=L;n++;//我们假设在终点处有第n+1个石头,则他到起点的距离为L int l=0,r=L; while(l<=r) { int mid=(l+r)/2; if(check(mid))l=mid+1;//说明二分结果小了,要向右二分 else r=mid-1;//说明结果大了,要向左二分 } printf("%d\n",l-1); }
2、子串
题目描述
有两个仅包含小写英文字母的字符串 A 和 B。现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新的字符串,请问有多少种方案可以使得这个新串与字符串 B 相等?注意:子串取出 的位置不同也认为是不同的方案。
输入输出格式
输入格式:
输入文件名为 substring.in。
第一行是三个正整数 n,m,k,分别表示字符串 A 的长度,字符串 B 的长度,以及问题描述所提到的 k,每两个整数之间用一个空格隔开。 第二行包含一个长度为 n 的字符串,表示字符串 A。 第三行包含一个长度为 m 的字符串,表示字符串 B。
输出格式:
输出文件名为 substring.out。 输出共一行,包含一个整数,表示所求方案数。由于答案可能很大,所以这里要求[b]输出答案对 1,000,000,007 取模的结果。[/b]
输入输出样例
6 3 1 aabaab aab
2
6 3 2 aabaab aab
7
6 3 3 aabaab aab
7
说明
对于第 1 组数据:1≤n≤500,1≤m≤50,k=1;
对于第 2 组至第 3 组数据:1≤n≤500,1≤m≤50,k=2; 对于第 4 组至第 5 组数据:1≤n≤500,1≤m≤50,k=m; 对于第 1 组至第 7 组数据:1≤n≤500,1≤m≤50,1≤k≤m; 对于第 1 组至第 9 组数据:1≤n≤1000,1≤m≤100,1≤k≤m; 对于所有 10 组数据:1≤n≤1000,1≤m≤200,1≤k≤m。
【题目分析】转自:https://blog.sengxian.com/solutions/noip-2015-day2#toc_6
dp题
设 f[i][j][k]f[i][j][k] 为串 AA 匹配到第 i−1i−1 个位置(位置从 00 开始),串 BB 匹配到 j−1j−1 个位置,而且恰好选串 AA 的 i−1i−1 号字符的方案总数。
设 s[i][j][k]s[i][j][k] 为串 AA 匹配到第 i−1i−1 个位置(位置从 00 开始),串 BB 匹配到 j−1j−1 个位置,的方案总数。可以知道 s[m][n][k]s[m][n][k]就是要求的答案。
考虑边界,空空相对,00 组有一种方法,所以有 s[i][0][0]=1s[i][0][0]=1。
接下来考虑状态转移方程:s[i][j][k]s[i][j][k] 是很容易求出来的。