CodeForces 14 E - Camels && D - Two Paths

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\n",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\n",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\n",ans);

    return 0;
}











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值