Simulation + thinking
Here's a question for you U L R D ULRD ULRD is a string of four characters, U U U stands for walking up L L L left R R R right D D D down, then give the point ( x , y ) (x,y) (x,y) let you judge whether it is possible for the robot to carry out this series of operations without passing through points in the diagram ( x , y ) (x,y) (x,y) output path if possible, output if impossible I m o p s s i b l e Imopssible Imopssible
Idea: enumerate the full arrangement in four directions and avoid it if possible ( x , y ) (x,y) (x,y) then the robot must be able to choose one direction first and go straight before going the other direction. The code is as follows:
#include<bits/stdc++.h> using namespace std; int mx, my; bool get_p(int u, int r, int d, int l, int a[]){ string res = ""; for(int i = 0; i < 4; ++ i) if(a[i] == 1) while(u --) res += 'U'; else if(a[i] == 2) while(r --) res += 'R'; else if(a[i] == 3) while(d --) res += 'D'; else while(l --) res += 'L'; bool flag = true; int sx = 0, sy = 0; for(int i = 0; i < res.size(); ++ i){ if(res[i] == 'L') sx --; else if(res[i] == 'R') sx ++; else if(res[i] == 'D') sy --; else sy ++; if(sx == mx && sy == my){ flag = false; break; } } if(flag){ cout << res << endl; return true; } return false; } int main(){ int T; cin >> T; while(T --){ cin >> mx >> my; string s; cin >> s; int l, r, u, d; l = r = u = d = 0; int sx = 0, sy = 0; //Less than 0 left and lower, more than 0 right and upper for(int i = 0; i < s.size(); ++ i) if(s[i] == 'L') l ++, sx --; else if(s[i] == 'R') r ++, sx ++; else if(s[i] == 'D') d ++, sy --; else u ++, sy ++; if(mx == 0 && my == 0) puts("Impossible"); else if(mx == sx && my == sy) puts("Impossible"); else{ bool flag = false; int a[5] = {1, 2, 3, 4}; do{ if(get_p(u, r, d, l, a)){ flag = true; break; } }while(next_permutation(a, a + 4)); if(!flag) puts("Impossible"); } } return 0; }
Probability, expectation, three points
Meaning: K o t o r i Kotori Kotori sets off fireworks. It takes him a lot of money to make a fireworks n n It takes n minutes to set off all these fireworks m m m minutes, the probability of releasing perfect fireworks is p p p let you expect to release a perfect fireworks
Idea: at least let go x x It takes x times to release the perfect fireworks n x + m nx+m nx+m, let the probability of not releasing perfect fireworks be q = 1 − p q=1-p q=1 − p, release x x The probability that x fireworks have at least one perfect fireworks is 1 − q x 1-q^x 1 − qx, the expectation is 1 1 − q x \frac{1}{1-q^x} 1 − qx1, so the expected number of times is f ( x ) = n x + m 1 − q x f(x)=\frac{nx+m}{1-q^x} f(x)=1 − qxnx+m. it can be found that this is a concave function, that is, the peak value can be calculated by three points. The code is as follows
#include<bits/stdc++.h> using namespace std; const double eps = 1e-6; double n, m; double p; double f(int x){ return (n * x + m) / (1 - pow(1 - p, x)); } int main(){ int T; cin >> T; while(T --){ cin >> n >> m >> p; p /= 10000; int l = 0, r = 1e9; while(l <= r){ int ml = l + (r - l) / 3, mr = r - (r - l) / 3; if(f(ml) >= f(mr)) l = ml + 1; else r = mr - 1; } printf("%.10lf\n", f(r)); } return 0; }
thinking
Here are two numbers n n n and k k k. I want you to find a sequence: this sequence is 1 ∼ n 1\sim n 1 ∼ n arrangement with k k The number of k is satisfied g c d ( a i , i ) = 1 gcd(a_i,i)=1 gcd(ai, i)=1. If the sequence satisfying the condition is not found, it will be output − 1 -1 −1
thinking k = 0 k=0 Output when k=0 − 1 -1 − 1, because 1 1 The greatest common divisor of 1 and any number is 1 1 1. If it is an odd number 1 1 1 keep still every exchange a i a_i ai} and a i + 1 a_{i+1} ai+1} switching k / 2 k/2 k/2 pair, if k k If k is an even number, then from 1 1 1 start each exchange a i a_i ai} and a i + 1 a_{i+1} ai+1} switching k / 2 k/2 k/2 pair. principle g c d ( i , i + 1 ) = 1 gcd(i,i+1)=1 gcd(i,i+1)=1
The code is as follows
#include<bits/stdc++.h> using namespace std; const int N = 1e6 + 10; int n, k; int a[N]; int main(){ cin >> n>> k; for(int i = 1; i <= n; ++ i) a[i] = i; if(k == 0) puts("-1"); else{ int cnt = 1; if(k % 2) cnt ++; k /= 2; for(; k > 0 && cnt <= n; cnt += 2, -- k) swap(a[cnt], a[cnt + 1]); for(int i = 1; i <= n; ++ i) cout << a[i] << ' '; puts(""); } }
Dichotomy + thinking
Summary of the meaning of the topic: the red stone with the most scores between the two blue stones is the one with the most scores. It is directly sorted by two points. However, it is necessary to judge the one before the first blue stone and the one after the last blue stone (just set up two Sentinels directly)
The code is as follows
#include<bits/stdc++.h> using namespace std; const int N = 1e5 + 5, INF = 2e9; int n, m; int a[N], b[N]; void solve(){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; ++ i) scanf("%d", &a[i]); for(int i = 1; i <= m; ++ i) scanf("%d", &b[i]); sort(a + 1, a + n + 1); sort(b + 1, b + m + 1); int res = 0; b[0] = -INF, b[m + 1] = INF; for(int i = 0; i <= m; ++ i){ int l = upper_bound(a + 1, a + n + 1, b[i]) - a; int r = lower_bound(a + 1, a + n + 1, b[i + 1]) - a - 1; res = max(res, r - l + 1); } if(!res) puts("Impossible"); else printf("%d\n", res); } int main(){ int T; scanf("%d", &T); while(T --){ solve(); } return 0; }
Tree DP
Meaning: fight monsters. The blood volume of each monster is h p i hp_i hpi, you have to 1 1 Start playing at point 1, that is, the root node. You need to kill his father node before playing a monster. The price of killing a monster is the cost of the monster itself h p + hp+ hp + all sons directly connected to the monster h p hp hp. Now you have a kind of magic. Beating a monster can not consume any energy, so you can find out what you have 0 , 1 , 2 , . . . , n 0,1,2,...,n 0,1,2,..., the energy consumed in n magic (magic has been used before hitting monsters)
Idea: tree DP, backpack on tree
state
d
p
[
u
]
[
i
]
[
0
/
1
]
dp[u][i][0/1]
dp[u][i][0/1] represents the node
u
u
The subtree with u as the root has
i
i
i sons are not magic, node
u
u
u used / not used magic
Transfer:
f
[
u
]
[
j
+
k
]
[
0
]
=
m
i
n
(
f
[
u
]
[
j
+
k
]
[
0
]
,
f
[
u
]
[
j
]
[
0
]
+
m
i
n
(
f
[
v
]
[
k
]
[
0
]
,
f
[
v
]
[
k
]
[
1
]
)
)
f[u][j + k][0]=min(f[u][j+k][0],f[u][j][0]+min(f[v][k][0],f[v][k][1]))
f[u][j+k][0]=min(f[u][j+k][0],f[u][j][0]+min(f[v][k][0],f[v][k][1]))
f
[
u
]
[
j
+
k
]
[
1
]
=
m
i
n
(
f
[
u
]
[
j
+
k
]
[
1
]
,
f
[
u
]
[
j
]
[
1
]
+
m
i
n
(
f
[
v
]
[
k
]
[
0
]
,
f
[
v
]
[
k
]
[
1
]
+
a
[
v
]
)
)
f[u][j + k][1]=min(f[u][j+k][1],f[u][j][1]+min(f[v][k][0],f[v][k][1]+a[v]))
f[u][j+k][1]=min(f[u][j+k][1],f[u][j][1]+min(f[v][k][0],f[v][k][1]+a[v]))
code:
#include<bits/stdc++.h> #define ll long long using namespace std; const int N = 2e3 + 10; int n; int h[N], e[N], ne[N], idx; ll f[N][N][2]; //Node i has j child nodes alive. Is node i alive ll a[N]; int sz[N]; void add(int a, int b){ e[idx] = b, ne[idx] = h[a], h[a] = idx ++; } void dfs(int u){ f[u][0][0] = 0; f[u][1][1] = a[u]; sz[u] = 1; for(int i = h[u]; ~i; i = ne[i]){ int v = e[i]; dfs(v); for(int j = sz[u]; j >= 0; -- j) for(int k = sz[v]; k >= 0; -- k){ f[u][j + k][0] = min(f[u][j + k][0], f[u][j][0] + min(f[v][k][0], f[v][k][1])); f[u][j + k][1] = min(f[u][j + k][1], f[u][j][1] + min(f[v][k][0], f[v][k][1] + a[v])); } sz[u] += sz[v]; } } int main(){ int T; cin >> T; while(T --){ cin >> n; memset(h, -1, sizeof h); for(int i = 0; i <= n; ++ i) for(int j = 0; j <= n; ++ j) f[i][j][0] = f[i][j][1] = 1e18; for(int i = 2, x; i <= n; ++ i){ cin >> x; add(x, i); } for(int i = 1; i <= n; ++ i) cin >> a[i]; dfs(1); for(int i = n; i >= 0; -- i) cout << min(f[1][i][0], f[1][i][1]) << ' '; puts(""); } return 0; }