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;
}

TongChu
1 声望0 粉丝

练习编程两年半的个人练习生