A - Finite or not?
在除完$gcd$之后,只需要看 $q$ 的质因子是不是全部都被 $b$ 包含就行,但是注意每次要把 $b=gcd$ ,不然TLE
#include <bits/stdc++.h>using namespace std;typedef long long LL;typedef unsigned long long ULL;LL Gcd(LL a,LL b){if (b == 0) return a; return Gcd(b , a%b);}LL Lcm(LL a, LL b){ return a/Gcd(a,b)*b;}inline long long read(){ long long f = 1, x = 0;char ch = getchar(); while (ch > '9' || ch < '0'){if (ch == '-')f = -f;ch = getchar();} while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();} return x * f;}const int maxn = 1e6 + 10;int main(){ int T = read(); while(T--){ LL p = read(),q = read(),b = read(); if (p == 0 || p % q == 0){ cout << "Finite" << endl; continue; } LL g = Gcd(p,q),tag = 0; q /= g; while(b % q != 0){ g = Gcd(b,q); if (q != 1 && g == 1){ cout << "Infinite" << endl; tag = 1; break; } b = g; q /= g; } if (!tag) puts("Finite"); } return 0;}
B - XOR-pyramid
考虑$dp$处理问题,我们设 $dp[i][j]$ 是数组中以$i$ 为开头长度
为 $j+1$ 的代价,那么根据题意就有如下转移方程
$$dp[i][j] = dp[i][j-1] \bigoplus dp[i+1][j-1]$$
状态转移后重新定义$dp[i][j]$ 是数组中以$i$ 为开头,长度至少为 $j+1$ 的代价,那么就有
$$dp[i][j] = min(dp[i][j],min(dp[i][j-1],dp[i+1][j-1]))$$
最后的答案就$dp[l][r-l]$
C - Elevator
首先先考虑状态,定义状态$dp[i][j][ta][tb][tc]$ 表示当前被送走的人数加上在电梯上的人数为 $i$ ,电梯停在第 $j$ 层,里面三个人的去向分别为$ta,tb,tc$。
后面不记录4个人去向的原因是空间开不下,所以在一个人上电梯之后,必定不可能有人上电梯,这个时候枚举一个人下去,这样就可以用10x10x10的状态表示电梯上的人数状态。
考虑转移
- 如果已经送走了 $n$ 个人,那么电梯上的人不断下电梯就行
$dp(i,j,ta,tb,tc) = min(dp(i,j,ta,tb,tc),dp(i,ta,0,tb,tc) + abs(j - ta) + 1)$
$dp(i,j,ta,tb,tc) = min(dp(i,j,ta,tb,tc),dp(i,tb,ta,0,tc) + abs(j - tb) + 1)$
$dp(i,j,ta,tb,tc) = min(dp(i,j,ta,tb,tc),dp(i,tc,ta,tb,0) + abs(j - tc) + 1)$
- 如果还没有送走 $n$ 个人,那么首先枚举所有人下电梯状态如上转移方程,然后再枚举谁下电梯让新来的人上电梯,这里用$ans$指代$dp(i,j,ta,tb,tc)$
$ ans = min(ans,dp(i+1,ta,b[i+1],tb,tc) + abs(j - a[i+1]) + abs(a[i+1] - ta) + 2);$
$ ans = min(ans,dp(i+1,a[i+1],b[i+1],tb,tc) + abs(j - ta) + abs(a[i+1] - ta) + 2); $
$ ans = min(ans,dp(i+1,tb,ta,b[i+1],tc) + abs(j - a[i+1]) + abs(a[i+1] - tb) + 2);$
$ ans = min(ans,dp(i+1,a[i+1],ta,b[i+1],tc) + abs(j - tb) + abs(a[i+1] - tb) + 2) $
$ ans = min(ans,dp(i+1,tc,ta,tb,b[i+1]) + abs(j - a[i+1]) + abs(a[i+1] - tc) + 2); $
$ ans = min(ans,dp(i+1,a[i+1],ta,tb,b[i+1]) + abs(j - tc) + abs(a[i+1] - tc) + 2);$
$ ans = min(ans,dp(i+1,b[i+1],ta,tb,tc) + abs(j - a[i+1]) + abs(a[i+1] - b[i+1]) + 2);$
暴力转移即可
#include <bits/stdc++.h>using namespace std;typedef long long LL;typedef unsigned long long ULL;int Gcd(int a,int b){if (b == 0) return a; return Gcd(b , a%b);}int Lcm(int a, int b){ return a/Gcd(a,b)*b;}inline long long read(){ long long f = 1, x = 0;char ch = getchar(); while (ch > '9' || ch < '0'){if (ch == '-')f = -f;ch = getchar();} while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();} return x * f;}const int maxn = 2000 + 10;const int inf = 0x3f3f3f3f;int dp[maxn][10][10][10][10],a[maxn],b[maxn],n;int dfs(int i,int j,int ta,int tb,int tc){ if (dp[i][j][ta][tb][tc] != -1){ return dp[i][j][ta][tb][tc]; }else{ int ans = inf; if (i == n){ if (ta == 0 && tb == 0 && tc == 0){ return dp[i][j][ta][tb][tc] = 0; }else{ if (ta) ans = min(ans, dfs(i,ta,0,tb,tc) + abs(j - ta) + 1); if (tb) ans = min(ans, dfs(i,tb,ta,0,tc) + abs(j - tb) + 1); if (tc) ans = min(ans, dfs(i,tc,ta,tb,0) + abs(j - tc) + 1); return dp[i][j][ta][tb][tc] = ans; } }else{ if (ta) ans = min(ans, dfs(i,ta,0,tb,tc) + abs(j - ta) + 1); if (tb) ans = min(ans, dfs(i,tb,ta,0,tc) + abs(j - tb) + 1); if (tc) ans = min(ans, dfs(i,tc,ta,tb,0) + abs(j - tc) + 1); if (ta == 0){ ans = min(ans,dfs(i+1,a[i+1],b[i+1],tb,tc) + abs(j - a[i+1]) + 1); }else if (tb == 0){ ans = min(ans,dfs(i+1,a[i+1],ta,b[i+1],tc) + abs(j - a[i+1]) + 1); }else if (tc == 0){ ans = min(ans,dfs(i+1,a[i+1],ta,tb,b[i+1]) + abs(j - a[i+1]) + 1); }else{ ans = min(ans,dfs(i+1,ta,b[i+1],tb,tc) + abs(j - a[i+1]) + abs(a[i+1] - ta) + 2); ans = min(ans,dfs(i+1,a[i+1],b[i+1],tb,tc) + abs(j - ta) + abs(a[i+1] - ta) + 2); ans = min(ans,dfs(i+1,tb,ta,b[i+1],tc) + abs(j - a[i+1]) + abs(a[i+1] - tb) + 2); ans = min(ans,dfs(i+1,a[i+1],ta,b[i+1],tc) + abs(j - tb) + abs(a[i+1] - tb) + 2); ans = min(ans,dfs(i+1,tc,ta,tb,b[i+1]) + abs(j - a[i+1]) + abs(a[i+1] - tc) + 2); ans = min(ans,dfs(i+1,a[i+1],ta,tb,b[i+1]) + abs(j - tc) + abs(a[i+1] - tc) + 2); ans = min(ans,dfs(i+1,b[i+1],ta,tb,tc) + abs(j - a[i+1]) + abs(a[i+1] - b[i+1]) + 2); } return dp[i][j][ta][tb][tc] = ans; } }}int main(){ memset(dp,-1,sizeof(dp)); n = read(); for(int i=1; i<=n; i++){ a[i] = read(); b[i] = read(); } cout << dfs(0,1,0,0,0) << endl; return 0;}