zoukankan      html  css  js  c++  java
  • CodeForces 14 E

    D - Two paths

    仅仅想到了一个o(n^2)的解法。

    首先枚举删除一条边,必定得到两棵独立的树。计算两棵树的直径。保留最大乘积。

    首先两条路不相交,则必定能够分到两棵子树中,由于要乘积最大,所以两条路必为两棵子树的直径。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #include <stack>
    #include <map>
    #include <ctime>
    #include <iomanip>
    
    #pragma comment(linker, "/STACK:1024000000");
    #define EPS (1e-6)
    #define LL long long
    #define ULL unsigned long long
    #define _LL __int64
    #define INF 0x3f3f3f3f
    #define Mod 1000000007
    
    using namespace std;
    
    struct EDGE
    {
        int v,next;
    }edge[400];
    
    int Top;
    int head[210];
    
    void Link(int u,int v)
    {
        edge[Top].v = v;
        edge[Top].next = head[u];
        head[u] = Top++;
    }
    
    bool mark[210][210];
    
    int vis[210];
    
    queue<int> q;
    
    int bfs(int s,int b,int &len)
    {
        memset(vis,-1,sizeof(vis));
        vis[s] = 0;
        q.push(s);
    
        int f;
    
        while(q.empty() == false)
        {
            f = q.front();
            q.pop();
    
            for(int p = head[f];p != -1; p = edge[p].next)
            {
                if(edge[p].v != b && vis[edge[p].v] == -1)
                {
                    vis[edge[p].v] = vis[f]+1;
                    q.push(edge[p].v);
                }
            }
        }
        len = vis[f];
        return f;
    }
    
    int Cal(int x,int b)
    {
        int len;
        bfs(bfs(x,b,len),b,len);
        return len;
    }
    
    int main()
    {
        int n,i,j,u,v;
    
        scanf("%d",&n);
    
        Top = 0;
        memset(head,-1,sizeof(head));
        memset(mark,false,sizeof(mark));
        for(i = 1;i < n; ++i)
        {
            scanf("%d %d",&u,&v);
            Link(u,v);
            Link(v,u);
            mark[u][v] = mark[v][u] = true;
        }
    
        int Max = 0;
        int s1,s2;
        for(i = 1;i <= n; ++i)
            for(j = i+1;j <= n; ++j)
            {
                if(mark[i][j])
                {
                    Max = max(Max,(s1 = Cal(i,j))*(s2 = Cal(j,i)));
                }
            }
    
        printf("%d
    ",Max);
    
        return 0;
    }

    E - Camels

    简单的DP o(2*4*t*n)。

    dp[当前位置] [当前位数字 ] [当前位置属于第几个峰] [ 当前位的状态是下降还是上升]。

    剩下的就比較好想了。注意边界。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #include <stack>
    #include <map>
    #include <ctime>
    #include <iomanip>
    
    #pragma comment(linker, "/STACK:1024000000");
    #define EPS (1e-6)
    #define LL long long
    #define ULL unsigned long long
    #define _LL __int64
    #define INF 0x3f3f3f3f
    #define Mod 1000000007
    
    using namespace std;
    
    LL dp[20][5][11][2];
    
    int main()
    {
        memset(dp,0,sizeof(dp));
    
        int n,t,i,j,k,l;
    
        scanf("%d %d",&n,&t);
    
        dp[2][2][1][1] = 1;
        dp[2][3][1][1] = 2;
        dp[2][4][1][1] = 3;
    
        LL ans;
    
        for(i = 3;i <= n; ++i)
        {
            for(k = 0;k <= t; ++k)
            {
                for(j = 1;j <= 4; ++j)
                {
                    for(l = 1,ans = 0;l < j; ++l)
                        ans += dp[i-1][l][k][1];
                    dp[i][j][k][1] += ans;
    
                    if(k >= 1)
                    {
                        for(l = 1,ans = 0;l < j; ++l)
                            ans += dp[i-1][l][k-1][0];
                        dp[i][j][k][1] += ans;
                    }
    
                    for(l = j+1,ans = 0;l <= 4; ++l)
                        ans += dp[i-1][l][k][0];
                    for(l = j+1;l <= 4; ++l)
                        ans += dp[i-1][l][k][1];
                    dp[i][j][k][0] += ans;
                    //printf("i = %d j = %d k = %d a0 = %I64d a1 = %I64d
    ",i,j,k,dp[i][j][k][0] , dp[i][j][k][1]);
                }
            }
        }
    
        for(ans = 0,i = 1;i <= 4; ++i)
            ans += dp[n][i][t][0];
    
        printf("%I64d
    ",ans);
    
        return 0;
    }
    
    
    
    
    
    
    
    
    
    
    

  • 相关阅读:
    vim删除操作
    kubectl命令自动补全
    kubelet资源限制
    一道c语言运算符优先级问题
    c语言自加自减三道题
    C语言操作符优先级
    [word]2010中插入公式自动编号并且公式不自动缩小/变小
    [matlab]改变矩阵的大小并保存到txt文件
    dxut.h(29): fatal error C1083: Cannot open include file: 'dxsdkver.h': No such file or directory
    [vim]的关键字补全
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4496686.html
Copyright © 2011-2022 走看看