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;
}