近期刷题感悟2(思维,DP)
总结一下今天做的一些题吧,大佬们的思想果然nb,看题解看了好长时间。。。
The Lost Cow
Farmer John has lost his prize cow Bessie, and he needs to find her!
Fortunately, there is only one long path running across the farm, and Farmer John knows that Bessie has to be at some location on this path. If we think of the path as a number line, then Farmer John is currently at position x and Bessie is currently at position y (unknown to Farmer John). If Farmer John only knew where Bessie was located, he could walk directly to her, traveling a distance of |x−y|. Unfortunately, it is dark outside and Farmer John can't see anything. The only way he can find Bessie is to walk back and forth until he eventually reaches her position.
Trying to figure out the best strategy for walking back and forth in his search, Farmer John consults the computer science research literature and is somewhat amused to find that this exact problem has not only been studied by computer scientists in the past, but that it is actually called the "Lost Cow Problem" (this is actually true!).
The recommended solution for Farmer John to find Bessie is to move to position x+1, then reverse direction and move to position x−2, then to position x+4, and so on, in a "zig zag" pattern, each step moving twice as far from his initial starting position as before. As he has read during his study of algorithms for solving the lost cow problem, this approach guarantees that he will at worst travel 9 times the direct distance |x−y| between himself and Bessie before he finds her (this is also true, and the factor of 9 is actually the smallest such worst case guarantee any strategy can achieve).
Farmer John is curious to verify this result. Given x and y, please compute the total distance he will travel according to the zig-zag search strategy above until he finds Bessie.
输入
输出
9
这个题比较正常,它移动过程中经过目标位置就算,不一定要按距离死走;
#include<math.h> #include <iostream> #include<cstdio> #include<string> #include<algorithm> #include <map> #include <math.h> #include <set> #include<sstream> #include <unordered_map> #define maxn 1000000 #define minn 03xfxfxfxf #define modd 1000000000 using namespace std; int main() { long long int x,a,b,t=1,jk,sum=0; cin >> a >> b; while(1) { jk = a+t; //中转点 if(jk>=b&&b>=a||jk<=b&&b<=a) { sum+=abs(b-a); break; } sum+=abs(t*2); t=-2*t; //去了还得回来 //cout << jk << " " << sum <<" " << a << endl; } cout << sum << endl; return 0; }
小朋友的数字
有n个小朋友排成一列。每个小朋友手上都有一个数字,这个数字可正可负。规定每个小朋友的特征值等于排在他前面(包括他本人)的小朋友中连续若干个(最少有一个)小朋友手上的数字之和的最大值。
作为这些小朋友的老师,你需要给每个小朋友一个分数,分数是这样规定的:第一个小朋友的分数是他的特征值,其它小朋友的分数为排在他前面的所有小朋友中(不包括他本人),小朋友分数加上其特征值的最大值。
请计算所有小朋友分数的最大值,输出时保持最大值的符号,将其绝对值对p取模后输出。
输入
第二行包含n个数,每两个整数之间用一个空格隔开,表示每个小朋友手上的数字。
输出
样例输入 Copy
5 997
1 2 3 4 5
样例输出 Copy
21
提示
样例1小朋友的特征值分别为1、3、6、10、15,分数分别为1、2、5、11、21,最大值21对997的模是21。
对于 100%的数据,1 ≤ n ≤ 1,000,000,1 ≤ p ≤ 10^9,其他数字的绝对值均不超过 10^9。
这个题有毒,他不是在考你算法,它在考你读题
特征值:1-i的最大连续字段和;
分数:i以前的某一个小朋友的分数加上特征值的最大值;
我们可以想到我们要先求每个人的特征值,这个好解决(dp经典问题),之后我们要求出每个人的分数,顺便出最值:
#include<math.h> #include <iostream> #include<cstdio> #include<string> #include<algorithm> #include <map> #include <math.h> #include <set> #include<sstream> #include <unordered_map> #define maxn 1000009 #define minn 03xfxfxfxf #define modd 1000000000 using namespace std; long long a[maxn],b[maxn], p,n,x,pre,maxx=-11111111111111,ans; long long read() //快读 { long long s = 0;int w = 1; char ch = getchar(); while(!isdigit(ch)) {if(ch == '-') w = -1;ch = getchar();} while(isdigit(ch)) {s = s * 10 + ch - '0';ch = getchar();} return s * w; } int main() { n = read(), p = read(); for(int i=1;i<=n;i++) { x = read(); if(pre>0) x+=pre; pre =x; maxx=max(x,maxx); a[i]=maxx%p; //中间会爆longlong } ans =a[1]; b[1]=a[1]; long long maxn1=-10100000000; for(int i=2;i<=n;i++) { maxn1=max(maxn1,a[i-1]+b[i-1]); b[i]=maxn1; //把这一位的分数存下来 if(ans<maxn1) ans=maxn1%p; //找最值,同时防暴longlong } printf("%lld",ans%p); return 0; }
Hoofball
In preparation for the upcoming hoofball tournament, Farmer John is drilling his N cows (conveniently numbered 1…N, where 1≤N≤100) in passing the ball. The cows are all standing along a very long line on one side of the barn, with cow ii standing xi units away from the barn (1≤xi≤1000). Each cow is standing at a distinct location.
At the begiNing of the drill, Farmer John will pass several balls to different cows. When cow i receives a ball, either from Farmer John or from another cow, she will pass the ball to the cow nearest her (and if multiple cows are the same distance from her, she will pass the ball to the cow farthest to the left among these). So that all cows get at least a little bit of practice passing, Farmer John wants to make sure that every cow will hold a ball at least once. Help him figure out the minimum number of balls he needs to distribute initially to ensure this can happen, assuming he hands the balls to an appropriate initial set of cows.
输入
输出
样例输入 Copy
5
7 1 3 11 4
样例输出 Copy
2
这题看题解看了好久,我们先扫一遍序列,用”<” “ >“来标记传球方向,我们可以把分成多段,以”><“为分段标志;
这时分三种情况,
比如像这样给一个球就行 ">>>><"
">>><<<"像这种就得给两个球;
“>>><>"在最后一个>前我们要一个球就行,
#include<math.h> #include <iostream> #include<cstdio> #include<string> #include<algorithm> #include <map> #include <math.h> #include <set> #include<math.h> #include <iostream> #include<cstdio> #include<string> #include<algorithm> #include <map> #include <math.h> #include <set> #include<sstream> #include <unordered_map> #define maxn 1000009 #define minn 03xfxfxfxf #define mod 10000 using namespace std; long long read() { long long s = 0;int w = 1; char ch = getchar(); while(!isdigit(ch)) {if(ch == '-') w = -1;ch = getchar();} while(isdigit(ch)) {s = s * 10 + ch - '0';ch = getchar();} return s * w; } char s[105]; int x[105]; int main() { int n,sum=0; cin >> n; for(int i=0;i<n;i++) { cin >> x[i]; } sort(x,x+n); for(int i=0;i<n;i++) { if(i==0) s[i]='>'; else if(i==n-1) s[i] ='<'; else { if(abs(x[i]-x[i-1])>abs(x[i+1]-x[i])) { s[i]='>'; } else { s[i]='<'; } } } s[n]='>'; int cnt = 0; for(int i = 0; i < n; ) { int k = 0; while(s[i] == '>' && i < n) { i++; k++; } if(s[i+1] == '>') { cnt++; i++; } else { while(s[i] == '<' && i < n) { i++; } if(k > 1) { cnt += 2; } else { cnt++; } } } cout << cnt ; return 0; }

浙公网安备 33010602011771号