第一题:
复制代码
1
2
3
4
【题目描述】
农夫约翰被通知,他的一只奶牛逃逸了!所以他决定,马上出发,尽快把那只奶牛抓回来.
他们都站在数轴上.约翰在N(O≤N≤100000)处,奶牛在K(O≤K≤100000)处.约翰有两种办法移动,步行和瞬移:步行每秒种可以让约翰从x处走到x+l或x-l处;而瞬移则可让他在1秒内从x处消失,在2x处出现.然而那只逃逸的奶牛,悲剧地没有发现自己的处境多么糟糕,正站在那儿一动不动.
那么,约翰需要多少时间抓住那只牛呢?
复制代码
1
2
【输入格式】
仅有两个整数N和K
复制代码
1
2【输出格式】 最短时间
复制代码
1
2【样例输入】 5 17
复制代码
1
2【样例输出】 4
这一题就很水了,直接暴力搜索即可,这里就直接给出代码了:
AC代码:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <bits/stdc++.h>
using namespace std;
const int maxn=100000+10;
int a[maxn],b[maxn],c[maxn],tot;
int DFS(int szsh){
if(c[szsh]!=0)
DFS(c[szsh]);
tot++;
}
int main(){
int n,k,x;
cin>>n>>k;
if(n==k){
cout<<0<<endl;
return 0;
}
a[1]=n;
b[n]=1;
int head=0,tail=1;
while(head!=tail){
head++;
for(int i=1;i<=3;i++){
if(i==1)
x=a[head]+1;
if(i==2)
x=a[head]-1;
if(i==3)
x=a[head]*2;
if(x>=0&&b[x]==0&&x<=100000){
tail++;
a[tail]=x;
c[tail]=head;
if(x==k){
DFS(tail);
cout<<tot-1<<endl;
head=tail;
break;
}
b[x]=1;
}
}
}
return 0;
}
第二题:
复制代码
1
2
【题目描述】
FJ打算好好修一下农场中某条凹凸不平的土路。按奶牛们的要求,修好后的路面高度应当单调上升或单调下降,也就是说,高度上升与高度下降的路段不能同时出现在修好的路中。 整条路被分成了N段,N个整数A_1, ... , A_N (1 <= N <= 2,000)依次描述了每一段路的高度(0 <= A_i <= 1,000,000,000)。FJ希望找到一个恰好含N个元素的不上升或不下降序列B_1, ... , B_N,作为修过的路中每个路段的高度。由于将每一段路垫高或挖低一个单位的花费相同,修路的总支出可以表示为: |A_1 - B_1| + |A_2 - B_2| + ... + |A_N - B_N| 请你计算一下,FJ在这项工程上的最小支出是多少。FJ向你保证,这个支出不会超过2^31-1。
复制代码
1
2
【输入格式】
第1行: 输入1个整数:N * 第2..N+1行: 第i+1行为1个整数:A_i
复制代码
1
2【输出格式】 第1行: 输出1个正整数,表示FJ把路修成高度不上升或高度不下降的最小花费
复制代码
1
2
3
4
5
6
7
8
9【样例输入】 7 1 3 2 4 5 3 9
复制代码
1
2【样例输出】 3
复制代码
1
2
【样例解释】
FJ将第一个高度为3的路段的高度减少为2,将第二个高度为3的路段的高度增加到5,总花费为|2-3|+|5-3| = 3,并且各路段的高度为一个不下降序列 1,2,2,4,5,5,9。
这一题显然就比上一题难了,显然,这是一个DP加上最长不下降子序列以及最长不上升子序列问题,这样就得离散化处理,对于前i个数,我们需要关心的有两个值
1.把它变成单调序列需要的土,越少越好
2.第i个数的大小,越小越好
于是dp[i][j]表示考虑前i个数,第i个数是j时,至少需要的土第i个数是j时最少需要的土,就等于j和a[i]差的绝对值+ 第i-1个数小于等于j时至少需要土的最小值并且得结合滚动数组,得出状态转移方程:dp[i-1][j]=abs(a[i]-b[j])+min(dp[i-1][j]);
代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <bits/stdc++.h>
const int maxn=2000+10;
using namespace std;
int dp[maxn*3][maxn*3],a[maxn],b[maxn],t,ans,n;
int min(int a,int b){
return a<b?a:b;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+n+1);
for(int i=1;i<=n;i++)
dp[1][i]=abs(a[1]-b[i]);
for(int i=2;i<=n;i++){
int k=dp[i-1][1],temp;
for(int j=1;j<=n;j++){
k=min(dp[i-1][j],k);
temp=abs(a[i]-b[j]);
dp[i][j]=k+temp;
}
}
ans=dp[n][n];
for(int i=1;i<n;i++)
ans=min(ans,dp[n][i]);
cout<<ans;
return 0;
}
第三题直接骗分输出n-1竟然蒙对了两个样例点!!!rp也是够可以了。
最后
以上就是寒冷天空最近收集整理的关于赛后总结2018-08-13的全部内容,更多相关赛后总结2018-08-13内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复