• 无题6


    题解:

    第一题:类比只有三根,四根的柱子的汉诺塔,柱子越多越好,柱子盘子固定,步数一定,如果我有K个盘子,J个柱子,把P个盘子移到1个柱子的步数为F【P】【J】, 那么剩余K-P个盘子移到1个柱子就是F【K-P】【J-1】, 放P的柱子不能再放了,然后我们又有J个可以自由移动的柱子,

    所以f[ i ][ j ] = min(f[ k ][ j ] * 2 + f[ i - k ][ j -1 ]), 枚举k即可;

    #include<bits/stdc++.h>
    using namespace std;
    long long dp[70][70];
    
    
    
    int main(){
        freopen("hanoi.in","r",stdin);
        freopen("hanoi.out","w",stdout);
        int n, m;
        scanf("%d%d", &n, &m);
        
        memset(dp, 0x3f, sizeof(dp));
        
        dp[1][3] = 1;
        for(int i = 2; i <= n; i++) dp[i][3] = ((dp[i - 1][3] + 1) << 1) - 1;
        for(int i = 1; i <= 65; i++) dp[0][i] = 0, dp[1][i] = 1, dp[2][i] = 3;
        
        
        for(int i = 4; i <= m; i++)
            for(int j = 3; j <= n; j++){
                for(int k = 1; k <= j; k++)
                    dp[j][i] = min(2 * dp[j - k][i] + dp[k][i - 1], dp[j][i]);
            }
        printf("%lld
    ", dp[n][m]);
    }          
    View Code

    第二题:

    我只想说cyj太聪明了

    #include<bits/stdc++.h>
    using namespace std;
    const int M = 200005;
    char s[M]; int b[M];
    struct node{
        int val, id;
        bool operator < (const node &rhs) const{
            return val < rhs.val;
        }
    }a[M];
    
    int q[M], h, t;
    int main(){
        freopen("rank.in","r",stdin);
        freopen("rank.out","w",stdout);
        int n, fg = 0;
        scanf("%d", &n);
        char now = 'a';
        for(int i = 1; i <= n; i++){
            scanf("%d", &a[i].val), a[i].id = i; b[i] = a[i].val;
        }
        sort(a + 1, a + 1 + n);
        int lst = 0; a[n+1].id = -1;
        for(int i = 1; i <= n; i++){
            node p; p.val = i;
            int pos = lower_bound(a + 1, a + 1 + n, p) - a;
            if(b[a[pos].id + 1] > lst) s[a[pos].id] = now;
            else s[a[pos].id] = ++now;
            lst = b[a[pos].id + 1];
            if(now > 'z'){fg = -1;break;}
        }
        if(fg)puts("-1");
        else for(int i = 1; i <= n; i++)printf("%c", s[i]);
    } 
    View Code

    第三题:期望DP,以前讲过, 终于还是写了这道题

    F化简:f(u) = sum ( f(v) ) + deg(u) ,  v is u's child

    G化简:g(u) = g(fa(u)) + f(fa(u)) - f(u);

    注意求完f,然后用f更新g, 修改f[ 1 ] = 0,  因为1不会再往上走,但更新g之前不能改F1,是有实际有意的;

    #include<bits/stdc++.h>
    using namespace std;
    #define ex(i, u) for(int i = h[u]; i; i = G[i].nxt)
    const int mod = 1e9 + 7, M = 1e5 + 5;
    int P = 20, f[M], g[M], F[M], GV[M], dep[M], deg[M], anc[M][25], h[M], tot;
    struct edge{int nxt, v;}G[M<<1];
    void add(int u, int v){G[++tot].v = v, G[tot].nxt = h[u], h[u] = tot;}
    inline int moc(int a){return a >= mod ? a - mod : a;}
    void dfs1(int u, int fa){
        anc[u][0] = fa;
        for(int p = 1; p <= P; p++)
            anc[u][p] = anc[anc[u][p - 1]][p - 1];
        ex(i, u){
            int v = G[i].v;
            if(v == fa)continue;
            dfs1(v, u);
            f[u] = moc(f[u] + f[v]);
        }
        f[u] = moc(f[u] + deg[u]);
    }
    
    void dfs2(int u, int fa){
        dep[u] = dep[fa] + 1;    
         F[u] = moc(F[fa] + f[u]);
         GV[u] = moc(GV[fa] + g[u]);
        ex(i, u){
            int v = G[i].v;
            if(v == fa)continue;
            g[v] = (g[u] + f[u] - f[v] + mod) % mod;
            dfs2(v, u);
        }
    }
    
    int get(int u, int v){
        if(dep[u] < dep[v])swap(u, v);
        int t = dep[u] - dep[v];
        for(int p = 0; t; t >>= 1, p++)
            if(t & 1) u = anc[u][p];
        if(u == v) return u;
        
        for(int p = P; p >= 0; p--)
            if(anc[u][p] != anc[v][p])
                u = anc[u][p], v = anc[v][p];
        return anc[u][0];
    }
    
    
    int main(){
        freopen("tree.in","r",stdin);
        freopen("tree.out","w",stdout);
        int n, q, u, v;
        scanf("%d%d", &n, &q);
        for(int i = 1; i < n; i++){
            scanf("%d%d", &u, &v);
            add(u, v); add(v, u);
            deg[u]++; deg[v]++;
        }
        dfs1(1, 0);
        F[0] = -f[1];
        dfs2(1, 0);
        //for(int i = 1; i <= n; i++)printf("%d %d %d %d %d
    ", i, f[i], g[i], F[i], GV[i]);
        f[1] = 0;
        while(q--){
            scanf("%d%d", &u, &v);
            int lca = get(u, v), flca = anc[lca][0];
            int ans = ( (F[u] - F[lca] + GV[v] - GV[lca]) % mod + mod ) % mod;
            printf("%d
    ", ans);
        }
    }
    View Code
  • 相关阅读:
    DNS-解析、劫持、污染
    JavaScript-闭包注意事项
    Firefox-常用扩展
    Nginx-server_name匹配规则
    PHP-mysqllib和mysqlnd
    Nginx-缓冲原理及优化
    Linux-NFS原理介绍
    Linux-strace命令
    语音增强的几个基本算法
    【论文:麦克风阵列增强】Microphone Array Post-Filtering For Non-Stationary Noise Suppression
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9690767.html
Copyright © 2020-2023  润新知