首页 > 编程语言 >2024牛客寒假算法基础集训营1

2024牛客寒假算法基础集训营1

时间:2024-02-12 22:35:25浏览次数:39  
标签:int ll long 2024 牛客 pair using 集训营 define

2024牛客寒假算法基础集训营1

A

解题思路:

按照\(dfs\)出现顺序暴力判断即可。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    int n;
    cin >> n;
    string s;
    cin >> s;
    vector<bool> vis(40);
    for (auto c : s)
    {
        if (c == 'D')
        {
            vis['D' - 'A'] = true;
        }
        else if (c == 'F' && vis['D' - 'A'] == true)
        {
            vis[c - 'A'] = true;
        }
        else if (c == 'S' && vis['F' - 'A'] == true)
        {
            vis[c - 'A'] = true;
        }
    }
    if (vis['D' - 'A'] && vis['F' - 'A'] && vis['S' - 'A'])
    {
        cout << 1 << ' ';
    }
    else
    {
        cout << 0 << ' ';
    }
    for (int i = 0; i < 30; i++)
    {
        vis[i] = false;
    }
    for (auto c : s)
    {
        if (c == 'd')
        {
            vis['d' - 'a'] = true;
        }
        else if (c == 'f' && vis['d' - 'a'] == true)
        {
            vis[c - 'a'] = true;
        }
        else if (c == 's' && vis['f' - 'a'] == true)
        {
            vis[c - 'a'] = true;
        }
    }
    if (vis['d' - 'a'] && vis['f' - 'a'] && vis['s' - 'a'])
    {
        cout << 1 << ' ';
    }
    else
    {
        cout << 0 << ' ';
    }
    cout << endl;
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

B

解题思路:

如果\((2,0),(1,-1),(1,1)\)这三处有火,那么三把火就够了。

其余封锁起码四把火,左右各两把。

暴力记录枚举情况添火判断即可。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    int n;
    cin >> n;
    set<pii> s;
    bool l = false;
    bool tr = false;
    ll res = 3;
    ll minx = 1e18;
    ll maxx = -1e18;
    for (int i = 1; i <= n; i++)
    {
        ll r, c;
        cin >> r >> c;
        minx = min(minx, c);
        maxx = max(maxx, c);
        if (r == 1)
        {
            if (s.find({r + 1, c}) != s.end())
            {
                if (c < 0)
                {
                    l = true;
                }
                else if (c > 0)
                {
                    tr = true;
                }
            }
            if (s.find({r + 1, c - 1}) != s.end())
            {
                if (c - 1 >= 0)
                {
                    tr = true;
                }
                else
                {
                    l = true;
                }
            }
            if (s.find({r + 1, c + 1}) != s.end())
            {
                if (c + 1 > 0)
                {
                    tr = true;
                }
                else
                {
                    l = true;
                }
            }
        }
        else
        {
            if (s.find({r - 1, c}) != s.end())
            {
                if (c < 0)
                {
                    l = true;
                }
                else if (c > 0)
                {
                    tr = true;
                }
            }
            if (s.find({r - 1, c - 1}) != s.end())
            {
                if (c - 1 >= 0)
                {
                    tr = true;
                }
                else
                {
                    l = true;
                }
            }
            if (s.find({r - 1, c + 1}) != s.end())
            {
                if (c + 1 > 0)
                {
                    tr = true;
                }
                else
                {
                    l = true;
                }
            }
        }
        s.insert({r, c});
    }
    if (s.find({2, 0}) != s.end())
    {
        res--;
    }
    if (s.find({1, -1}) != s.end())
    {
        res--;
    }
    if (s.find({1, 1}) != s.end())
    {
        res--;
    }
    ll ans = 0;
    if (!l)
    {
        if (s.size())
        {
            auto x = minx;
            if (x <= 0)
            {
                ans += 1;
            }
            else
            {
                ans += 2;
            }
        }
        else
        {
            ans += 2;
        }
    }
    // cout << ans << endl;
    if (!tr)
    {
        if (s.size())
        {
            auto x = maxx;
            if (x >= 0)
            {
                ans += 1;
            }
            else
            {
                ans += 2;
            }
        }
        else
        {
            ans += 2;
        }
    }

    ans = min(ans, res);
    cout << ans << endl;
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

C

解题思路:

先求出总不满意度\(S\)

\(S_c - S_{min} \leq M\)

\(S_{min} \geq S_c - M\)

尝试插入发现,越往后插队,\(S_{min}\)越大,具有单调性,二分即可。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    ll n, q, t;
    cin >> n >> q >> t;
    vector<ll> a(n + 1), pre(n + 10);
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    sort(a.begin() + 1, a.end());
    ll sum = 0;
    for (int i = 1; i <= n; i++)
    {
        sum += (n - i + 1) * a[i];
        pre[i] = a[i] + pre[i - 1];
    }
    while (q--)
    {
        ll m;
        cin >> m;
        auto check = [&](int mid)
        {
            ll cur = t * (n - mid + 1);
            return cur <= m;
        };
        int l = 0;
        int r = n + 1;
        while (l + 1 < r)
        {
            int mid = l + r >> 1;
            if (check(mid))
            {
                r = mid;
            }
            else
            {
                l = mid;
            }
        }
        cout << pre[r - 1] + t << endl;
    }
}

int main()
{
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

D

解题思路:

\((-10^9 \leq M \leq 10^9)\)。

累乘发现,\(9! \times 9! > 10^9\)。也就是说出现\(19\)个不同的数字后怎么改绝对值都会大于\(10^9\)。当然,\(0\)除外。

实际上,我们将这少数不同的数分别变成从\(0\)开始不断累加或者累减,哪怕\(n = 2\),最多\(\sqrt{10^9}\)次之后,序列累乘值一定突破询问上限。

所以,我们可以\(O(n\sqrt{10^9})\)内求出所有可得到的数字。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
const int N = 1e5 + 10;
const int inf = 1e9;
int n, q;
ll a[N];
set<ll> s, ans;

bool check(ll x)
{
    ll res = 1;
    for (int i = 1; i <= n; i++)
    {
        res *= a[i] + x;
        if (abs(res) > inf)
        {
            return false;
        }
    }
    ans.insert(res);
    return true;
}

void solve()
{
    cin >> n >> q;
    ans.insert(0);
    for (int i = 1; i <= n; i++)
    {
        scanf("%lld", &a[i]);
        s.insert(a[i]);
    }
    if (s.size() < 20)
    {
        // 将i从1/-1开始递增和递减,最多根号n次
        for (auto i : s)
        {
            ll cur = -i + 1;
            while (check(cur))
            {
                cur++;
            }
            cur = -i - 1;
            while (check(cur))
            {
                cur--;
            }
        }
    }
    while (q--)
    {
        int x;
        scanf("%d", &x);
        if (ans.count(x))
        {
            puts("Yes");
        }
        else
        {
            puts("No");
        }
    }
}

int main()
{
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

E

解题思路:

数据范围很小,对于每场比赛对决枚举所有胜负可能。

\(O(m \times 3^m)\)

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    int n, m;
    cin >> n >> m;
    vector<int> a(n + 1);
    vector<pii> q;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    for (int i = 1; i <= m; i++)
    {
        int u, v;
        cin >> u >> v;
        if (u == 1 || v == 1)
        {
            a[1] += 3;
            continue;
        }
        q.push_back({u, v});
    }
    m = q.size();
    ll ans = 1e18;
    ll sum = pow(3, m);
    for (int i = 0; i < sum; i++)
    {
        ll t = i;
        vector<int> p;
        vector<int> b = a;
        for (int i = 1; i <= m; i++)
        {
            p.push_back(t % 3);
            t /= 3;
        }
        int cur = 0;
        for (auto x : p)
        {
            int u = q[cur].fi;
            int v = q[cur].se;
            cur++;
            if (x == 0)
            {
                b[u]++;
                b[v]++;
            }
            else if (x == 1)
            {
                b[u] += 3;
            }
            else
            {
                b[v] += 3;
            }
        }
        ll cnt = 0;
        for (int i = 1; i <= n; i++)
        {
            if (b[i] > b[1])
            {
                cnt++;
            }
        }
        ans = min(ans, cnt + 1);
    }
    cout << ans << endl;
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

F

解题思路:

本题考察第二类斯特林数的通项公式。

\[S(n,m) = {n \brace m} = \frac{1}{m!} \times \sum\limits_{k = 0}^{m}((-1)^{k}\times\binom{m}{k} \times (m - k)^{n}) \]

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
const int N = 1e5;
const int mod = 1e9 + 7;
ll f[N + 1];
ll invf[N + 1];

ll qmi(ll a, ll b)
{
    ll res = 1;
    while (b)
    {
        if (b & 1)
        {
            res = res * a % mod;
        }
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

ll C(ll a, ll b)
{
    if (b == 0 || a == b)
    {
        return 1;
    }
    return (f[a] * invf[b] % mod) * invf[a - b] % mod;
}

void solve()
{
    int n, m;
    cin >> n >> m;
    if (n < m)
    {
        cout << 0 << endl;
        return;
    }
    f[0] = 1;
    for (int i = 1; i <= N; i++)
    {
        f[i] = f[i - 1] * i % mod;
    }
    invf[N] = qmi(f[N], mod - 2) % mod;
    for (int i = N - 1; i; i--)
    {
        invf[i] = invf[i + 1] * (i + 1) % mod;
    }
    ll ans = 0;
    for (int i = 0; i <= m; i++)
    {
        ll sign = (i & 1) ? -1 : 1;
        ans = (ans + (sign * C(m, i) * qmi(m - i, n) % mod)) % mod;
        ans = (ans + mod) % mod;
    }
    ans = ans * invf[m] % mod;
    cout << ans << endl;
}

int main()
{
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

G

解题思路:

显然,满减券的时候小的都叠加起来,手机里的钱加满减能得到上限。记得将手机里没用完的钱加上。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    ll n, m;
    cin >> n >> m;
    vector<pii> v(n + 1);
    for (int i = 1; i <= n; i++)
    {
        cin >> v[i].fi >> v[i].se;
    }
    sort(v.begin() + 1, v.end());
    ll pre = 0;
    ll ans = m;
    for (int i = 1; i <= n; i++)
    {
        pre += v[i].se;
        if (v[i].fi - pre <= m)
        {
            ans = max(ans, v[i].fi + m - (v[i].fi - pre));
        }
    }
    cout << ans << endl;
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

H

解题思路:

我们总重量枚举二进制中所有的\(1\)位,将该为改为\(0\),同时低位全部变为\(1\)进行讨论,记得最后总重量本身讨论一下。

举例:\(m = 1101010100\)

将其划分为几段

\([0,0111111111]\)

$ [1000000000,1011111111]$

\([1100000000,1100111111]\)

\([1101000000,1101001111]\)

\([1101010000,1101010011]\)

\([1101010100]\)

\(m\)中有\(5\)个一,所以前五段对应的就是这些一的变化讨论。最后一个就是总重量本身讨论。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    int n, m;
    cin >> n >> m;
    vector<int> v(n + 1), w(n + 1);
    for (int i = 1; i <= n; i++)
    {
        cin >> v[i] >> w[i];
    }
    ll ans = 0;
    ll cur = 0;
    ll res = 0;
    for (int i = 30; i >= 0; i--)
    {
        if (m >> i & 1)
        {
            res = 0;
            ll t = cur + (1 << i) - 1;
            for (int j = 1; j <= n; j++)
            {
                if ((w[j] | t) == t)
                {
                    res += v[j];
                }
            }
            ans = max(ans, res);
            cur += 1 << i;
        }
    }
    res = 0;
    for (int i = 1; i <= n; i++)
    {
        if ((w[i] | cur) == cur)
        {
            res += v[i];
        }
    }
    ans = max(ans, res);
    cout << ans << endl;
}

int main()
{

    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

I

解题思路:

按照题目所给构造方法进行构造,然后统计二者某一数值的平均或者其他统计特征,找到明显区别,即可判断。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    ll n;
    cin >> n;
    n = 1e5;
    double s = 0;
    for (int i = 1; i <= n; i++)
    {
        ll a, b, c;
        cin >> a >> b >> c;
        s += c;
    }
    s /= n;
    if (s >= 20)
    {
        puts("buaa-noob");
    }
    else
    {
        puts("bit-noob");
    }
}

int main()
{

    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

J

解题思路:

二分。

每次二分判断尝试构造任务过程,使得二者过程期间最大距离小于\(mid\),存在则说明\(mid\)在逼近。

在构造过程当中,假设我们当前遍历到了\(i\)处,此时有一个人一定在\(a_i\)处。查看另一位可出现的位置集合。\((集合初始就是只有(x,y),其余后续随着遍历插入)\)

如果存在\(abs(a_i - a_j) > mid\),此时我们就应当将\(a_j\)移出集合,因为\(a_j\)参与构建这一步会使得过程最大值过大。如果将集合内所有\(a_j\)删除后,集合为空,则说明这一步二者间的距离不可能小于等于\(mid\)。

对于\(i - 1\)删去的\(a_j\),即使\(abs(a_{i + 1} - a_j) \leq mid\),\(a_j\)理论上已不可能和\(a_{i + 1}\)同时出现促成一对。

因为,如果\(a_{i + 1}\)的对象能选\(a_j\),说明这一步一定是有一个人从\(a_i\)走到\(a_{i + 1}\),因为在\(i\)时刻一定有一个人在\(a_i\)。

我们按照时间倒推,如果\(i + 1\)时刻两人位置是\((a_{i +1},a_j)\),那么\(i\)时刻两人位置就是\((a_i,a_j)\),即非法状态。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    int n, x, y;
    cin >> n >> x >> y;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
    }
    ll l = -1;
    ll r = 1e9 + 1;
    auto check = [&](ll mid)
    {
        set<int> s;
        if (abs(x - y) > mid)
        {
            return false;
        }
        s.insert(x);
        s.insert(y);
        for (int i = 1; i <= n; i++)
        {
            while (s.size() && abs((*s.begin()) - a[i]) > mid)
            {
                s.erase(s.begin());
            }
            while (s.size() && abs((*s.rbegin()) - a[i]) > mid)
            {
                s.erase(*s.rbegin());
            }
            if (s.empty())
            {
                return false;
            }
            s.insert(a[i]);
        }
        return true;
    };
    while (l + 1 < r)
    {
        ll mid = l + r >> 1;
        if (check(mid))
        {
            r = mid;
        }
        else
        {
            l = mid;
        }
    }
    cout << r << endl;
}

int main()
{
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

K

解题思路:

\(n\)个点,\(n\)条边。基环树。

找到每个环。对该环搜索。每个结点开始有\(5\)种选择,依次顺着选下去,如果能沿着环走回来,说明得到一份使得该环上所有题都正确的答案集合。

将所有环的正确答案集合数量累乘,即答案。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
const int mod = 998244353;
void solve()
{
    int n;
    cin >> n;
    vector<int> a(n + 1);
    vector<string> s(n + 1);
    vector<int> indeg(n + 1);
    vector<bool> vis(n + 1);
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i] >> s[i];
        indeg[a[i]]++;
    }
    queue<int> q;
    for (int i = 1; i <= n; i++)
    {
        if (!indeg[i])
        {
            q.push(i);
        }
    }
    while (q.size())
    {
        auto t = q.front();
        q.pop();
        indeg[a[t]]--;
        vis[t] = true;
        if (!indeg[a[t]])
        {
            q.push(a[t]);
        }
    }
    ll ans = 1;
    for (int i = 1; i <= n; i++)
    {
        if (vis[i])
        {
            continue;
        }
        int u = i;
        int v = u;
        while (true)
        {
            vis[v] = true;
            v = a[v];
            if (v == u)
            {
                break;
            }
        }
        int cnt = 0;
        for (int j = 0; j < 5; j++)
        {
            v = u;
            int idx = j;
            while (true)
            {
                idx = s[v][idx] - 'A';
                v = a[v];
                if (v == u)
                {
                    break;
                }
            }
            if (s[u][idx] == s[u][j])
            {
                cnt++;
            }
        }
        ans = ans * cnt % mod;
    }
    cout << ans << endl;
}

int main()
{

    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

L

解题思路:

简单画个图,答案为\(3wc\)。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    ll c,d,h,w;
    cin >> c >> d >> h >> w;
    cout << 3 * w * c << endl;
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

M

解题思路:

分别从左和右开始排放。

如果总长度是\(6\)的倍数只需从任意一端排放依次,否则就是两次排放可能之和。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    int n;
    cin >> n;
    if (n % 6 == 0)
    {
        cout << n / 6 << endl;
    }
    else
    {
        cout << (n / 6) * 2 << endl;
    }
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }

    return 0;
}

标签:int,ll,long,2024,牛客,pair,using,集训营,define
From: https://www.cnblogs.com/value0/p/18014193

相关文章

  • 牛客周赛 Round 32
    牛客周赛Round32小红的01背包代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;usingpii=pair<ll,ll>;#definefifirst#definesesecondusingi128=__int128_t;usingpiii=pair<ll,pair<ll,ll>>;voidsolve(......
  • 2024牛客寒假算法基础集训营2个人补题题解(K、D)
    比赛链接:2024牛客寒假算法基础集训营2K、TokitsukazeandPassword(easy)题面看着很难实际上只要暴力的东西,赛时看了眼题面就溜了血亏爆搜,枚举\(abcd\)和_可能的值,枚举的情况只有\(9*8*7*6*9=27216\)种。判断按照枚举出的对应值排列出的密码是否满足条件,满足就\(ans++\)写完......
  • 2024-02-12 闲话
    昨天去避暑山庄看夜灯。灯展确实蛮漂亮照片选摘,虽然有点虚但是我妈妈在路上跟我说“诶看前面的马!”我往左扭头看到了这个,不觉得意外。但是我妈说不对,是你右边的那个!然后我看到了个这不禁让我想起来这个知乎回答虽然我妈并不是说啥是啥,但是确实有这样的桥段是......
  • 2024寒假自主提升日记
    2.7闲话做题纪要SP26368PWRANDMOD-PowerandMod龟速乘板子。点击查看代码#definell__int128_tllread(){llx=0,f=1;charc=getchar();while(c>'9'||c<'0'){if(c=='-'){f=-1;......
  • 牛客2.7比赛E,F题
    链接:https://ac.nowcoder.com/acm/contest/67743/E来源:牛客网智乃最近学习了冒泡排序和最长子段和,所以她现在想把它们合并成一个新的算法。众所周知,冒泡排序是一种通过交换相邻元素实现排序的算法,最长子段和是指从一个数组aaa中取出一段连续的非空数组区间[l,r][l,r][l,r],最大......
  • #13 2024.2.8
    大概能从#12和#13的日期看出,博主到底摆了多久。博主没救了呜呜呜wuwuwuwuuwu。hbxql。568.xsy5348栞569.xsy5349Metropolis570.xsy5350bus571.xsy5351重排572.xsy5352黄焖鸡573.xsy5353Utopiosphere574.loj3706「ZJOI2022」树updateon2024.2.11:康......
  • 逆向实战29——某度-某家号2024旋转验证码识别
    前言本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!目标网站aHR0cHM6Ly9hdXRob3IuYmFpZHUuY29tL2hvbWU/ZnJvbT1iamhfYXJ0aWNsZSZhcHBfaWQ9MTU2NTA5MjE0MjUwO......
  • 2024牛客寒假算法基础集训营2 补题
    2024牛客寒假算法基础集训营2补题A.TokitsukazeandBracelet签到模拟参考代码:#include<bits/stdc++.h>usingnamespacestd;#definefffirst#definesssecond#defineebemplace_back#defineall(u)u.begin(),u.end()#defineendl'\n'#definedebug(x)cout......
  • 2024春晚刘谦魔术揭秘
    2024春晚刘谦魔术揭秘!魔术步骤任意4张扑克牌,叠在一起对半撕开,再叠在一起名字有几个字,就把几张扑克,依次放到最下面再将最上面3张,插到剩下扑克牌的中间任意位置拿出最上面一张扑克牌藏起来任意拿出一张、两张或三张扑克牌,再插到剩下扑克牌的中间任意位置如果是男生拿一张,如......
  • 寒假训练 2024/2/11凌晨
    紫书uva437标签:二位偏序,区间dp题意:给$n$种长方体,每种有无限块,要求罗列最高的高度。限制条件是在下面的长方体的长和宽要严格大于上面的。思路:思路很简单,题目给的$n的范围[1,50]$,模拟一下我们可以推断,每一种长方体有$A_3^{3}=6$种排列方式,我们把每一种的六种排列方式......