• 《Mobile Service》


    一开始想的dp用了结构体来存位置,想试一试,但是无法证明正确性,很显然就wa了。

    这里的一个切入点就是位置数很小,一开始忽略了这里。

    后面可以发现,对于每一回合,如果我们枚举三个人的位置肯定复杂度不够,但是有一个人的位置必定在a[i],所以只需要枚举两个人的位置。

    dp[i][j][k] - 表示一个人在a[i],一个人在j,一个人在k。

    然后就可以dp了,有一点需要注意,除了移动到a[i]的位置,其他两个位置不能和a[i]位置重叠。(这里wa了一发)

    然后空间不够要用滚动数组。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    const int N = 1e5 + 5;
    const int M = 1e3 + 5;
    const LL Mod = 1000000;
    #define pi acos(-1)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        inline LL read(){
            LL x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
    }
    using namespace FASTIO;
    
    int c[205][205],a[1005],dp[2][205][205],n,q;//0 - 移动peo1,1 - 移动peo2,2 - 移动peo3
    int main()
    {
        n = read(),q = read();
        for(int i = 1;i <= n;++i) {
            for(int j = 1;j <= n;++j) {
                c[i][j] = read();
            }
        }
        for(int i = 1;i <= q;++i) a[i] = read();
        memset(dp,0x3f3f3f,sizeof(dp));
        a[0] = 1;
        dp[0][2][3] = 0;
        int ans = INF;
        for(int i = 1;i <= q;++i) {
            memset(dp[i % 2],0x3f3f3f,sizeof(dp[i % 2]));
            for(int j = 1;j <= n;++j) {
                for(int k = 1;k <= n;++k) {
                    int cost1 = c[a[i - 1]][a[i]];
                    int cost2 = c[j][a[i]];
                    int cost3 = c[k][a[i]];
                    if(j != a[i] && k != a[i] && dp[i % 2][j][k] > dp[(i + 1) % 2][j][k] + cost1) {
                        dp[i % 2][j][k] = dp[(i + 1) % 2][j][k] + cost1;
                    }
                    if(a[i - 1] != a[i] && k != a[i] && dp[i % 2][a[i - 1]][k] > dp[(i + 1) % 2][j][k] + cost2) {
                        dp[i % 2][a[i - 1]][k] = dp[(i + 1) % 2][j][k] + cost2;
                    }
                    if(a[i - 1] != a[i] && j != a[i] && dp[i % 2][j][a[i - 1]] > dp[(i + 1) % 2][j][k] + cost3) {
                        dp[i % 2][j][a[i - 1]] = dp[(i + 1) % 2][j][k] + cost3;
                    }
                }
            }
        }
        for(int i = 1;i <= n;++i) {
            for(int j = 1;j <= n;++j) {
                ans = min(ans,dp[q % 2][i][j]);
            }
        }
        printf("%d
    ",ans);
        system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    Educational Codeforces Round 20 D. Magazine Ad
    Educational Codeforces Round 20 C. Maximal GCD
    紫书第三章训练2 暴力集
    Educational Codeforces Round 20 B. Distances to Zero
    Educational Codeforces Round 20 A. Maximal Binary Matrix
    紫书第三章训练1 D
    紫书第一章训练1 D -Message Decoding
    HAZU校赛 Problem K: Deadline
    Mutual Training for Wannafly Union #8 D
    紫书第三章训练1 E
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/14406047.html
Copyright © 2020-2023  润新知