//https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190806114008215-138720377.jpg

QBXT-FOUR

2023.11.8 场四

T1

写了个 \(O(n^3)\) 的 DP,应该是跑不过 \(3000\) 的点的但是过了,然后写了一下特殊性质。

\(f[i][j]\) 表示考虑了 \(i\sim n\) 的数,最后一个选的值是 \(j\) 能获得的最大值。

然后三层循环,枚举 \(i,j\),以及能转移到 \(j\) 的位置 \(o\)

那么转移方程就是:

\[f[i][j] = f[i + 1][o] + (o - k - j) \times j \]

对于一些边界情况,例如之前没选的之类的,要先预处理一下:

\[f[i][j] = max(f[i][j], j \times (n - j + 1)) \]

/*
 * @Author: Aisaka_Taiga
 * @Date: 2023-11-08 08:20:03
 * @LastEditTime: 2023-11-08 11:40:06
 * @LastEditors: Aisaka_Taiga
 * @FilePath: \Desktop\T1.cpp
 * The heart is higher than the sky, and life is thinner than paper.
 */
#include <bits/stdc++.h>

#define int long long
#define N 3100

using namespace std;

inline int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();}
    while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return x * f;
}

int n, k, ans, f[N][N];

inline void dfs(int x, int sum)
{
    if(x <= 0) return ans = max(sum, ans), void();
    for(int i = x; i >= 1; i --)
        dfs(i - k - 1, sum + i * (x - i + 1));
    return ;
}

signed main()
{
    // freopen("55.txt", "r", stdin);
    n = read(), k = read();
    if(k == n)
    {
        ans = (n / 2 + 1) * (n - (n / 2 + 1) + 1);
        cout << ans << endl;
        return 0;
    }
    if(n <= 8)
    {
        dfs(n, 0);
        cout << ans << endl;
        return 0;
    }
    for(int i = n; i >= 1; i --)
    {
        for(int j = n; j >= i; j --)
        {
            f[i][j] = max(f[i][j], j * (n - j + 1));
            for(int o = j + k; o <= n; o ++)
                f[i][j] = max(f[i][j], f[i + 1][o] + (o - k - j) * j);
        }
    }
    for(int i = 1; i <= n; i ++) ans = max(ans, f[1][i]);
    cout << ans << endl;
    return 0;
}
/*
20 3
*/

T2

发现如果随机赋的话,相同的概率很小。

所以直接输出随机数,check 只会 \(O(n^2)\) 的,感觉加了会超时,所以没写。

/*
 * @Author: Aisaka_Taiga
 * @Date: 2023-11-08 10:24:52
 * @LastEditTime: 2023-11-08 13:56:53
 * @LastEditors: Aisaka_Taiga
 * @FilePath: \Desktop\T2.cpp
 * The heart is higher than the sky, and life is thinner than paper.
 */
#include <bits/stdc++.h>

#define int long long
#define N 1000100

using namespace std;

inline int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();}
    while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return x * f;
}

const int nn = 3e7;

int n, m, a[N], siz[N], ff;
map<int, int> mp;
vector<int> g[N];

signed main()
{
    srand(1919810);
    n = read(), m = read();
    for(int i = 1; i <= n - 1; i ++)
    {
        int u = read(), v = read();
        g[u].push_back(v);
        g[v].push_back(u);
    }
    if(n < 63 && m >= pow(2, n - 1))
    {
        for(int i = 0; i < n; i ++)
            cout << pow(2, i) << " ";
        return 0;
    }
    int xx = nn / n;
    for(int i = 1; i <= n; i ++)
        a[i] = rand() % m;
    for(int i = 1; i <= n; i ++)
        cout << a[i] << " ";
    return 0;
}

T3

看到题目里里面有个 \(p\) 数组,那个是 \(1\sim n\) 的一个排列,那么我们直接枚举全排列,然后用题目给的代码 check 一下就好了。

/*
 * @Author: Aisaka_Taiga
 * @Date: 2023-11-08 10:51:04
 * @LastEditTime: 2023-11-08 10:58:58
 * @LastEditors: Aisaka_Taiga
 * @FilePath: \Desktop\T3.cpp
 * The heart is higher than the sky, and life is thinner than paper.
 */
#include <bits/stdc++.h>

#define pii pair<int, int>
#define int long long
#define N 100

using namespace std;

inline int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();}
    while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return x * f;
}

int n, k, ans, mp[N][N], dis[N], d[N], vis[N], p[N];
priority_queue<pii> q;

inline void check()
{
    memset(d, 0x3f, sizeof d);
    d[1] = 0;
    for(int i = 1; i <= n; i ++)
    {
        int nw = p[i];
        for(int v = 1; v <= n; v ++)
            if(d[v] > d[nw] + mp[nw][v])
                d[v] = d[nw] + mp[nw][v];
    }
    for(int i = 1; i <= n; i ++)
        if(d[i] != dis[i]) return ;
    ans ++;
    return ;
}

inline void Dij()
{
    q.push({0, 1});
    memset(dis, 0x3f, sizeof dis);
    dis[1] = 0;
    while(!q.empty())
    {
        int u = q.top().second;
        q.pop();
        if(vis[u]) continue;
        vis[u] = 1;
        for(int i = 2; i <= n; i ++)
        {
            if(dis[i] > dis[u] + mp[u][i])
                dis[i] = dis[u] + mp[u][i];
        }
    }
    return ;
}

signed main()
{
    n = read();
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= n; j ++)
            mp[i][j] = read();
    Dij();
    int xx = 1;
    for(int i = 1; i <= n; i ++) xx *= i, p[i] = i;
    // for(int i = 1; i <= n; i ++)
    //     cout << dis[i] << " ";
    // cout << endl;
    for(int i = 1; i <= xx; i ++)
    {
        next_permutation(p + 1, p + n + 1);
        check();
    }
    cout << ans << endl;
    return 0;
}
/*
20 3
*/
posted @ 2023-11-09 07:58  北烛青澜  阅读(2)  评论(0编辑  收藏  举报