• CF1293E-Xenon's Attack on the Gangs 树状DP


    0边把图分成两个部分,这两个部分的路径之间,mex起码为1,都对答案产生1的贡献。

    然后1边接在0边旁边,把图分成了更小的两个部分(0,1的两端),和一些不会再产生新的贡献的区域,这两个更小的部分路径之间,mex起码为2,都对答案又产生了1的贡献。(他们在刚刚算mex起码为1的时候,已经贡献过1了,所以再贡献1,mex就起码为2了)。

    依次类推,我们发现最后只有一条链上的边放置的是有意义的,其他边都可以随便放,反正不会产生贡献。

    我们考虑这种情况下如何求解。

    如果只考虑一条链,dp[i][j]从i边开始到j边 结束,放置0~(j-i)这些边的最大贡献。dp[i][j] = lcnt[i] * rcnt[j] + max(dp[i + 1][j],dp[i][j - 1])。

    这道题允许O(N^2)做法,所以我们可以枚举每条链,然后用这个DP就行了。

    siz[i][root]以root为根,i的孩子有多少。fa[i][root]以root为根,i的父亲是谁。

    dp[x][y]就是把x和y之间的路径放置的最大贡献。和上面转移是一样的,只不过看 x的时候,就把y当根,来使得所计算的贡献都是正确的。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 using namespace std;
     5 typedef long long ll;
     6 const int MAXN = 3100;
     7 int cnt,n;
     8 int head[MAXN],siz[MAXN][MAXN],fa[MAXN][MAXN],nxt[2 * MAXN],to[2 * MAXN];
     9 ll dp[MAXN][MAXN],ans;
    10 void add(int x,int y)
    11 {
    12     nxt[++cnt] = head[x];
    13     to[cnt] = y;
    14     head[x] = cnt;
    15 }
    16 void dfs(int x,int root)
    17 {
    18     siz[x][root] = 1;
    19     for (int i = head[x];i;i = nxt[i])
    20     {
    21         if (to[i] == fa[x][root])
    22             continue;
    23         fa[to[i]][root] = x;
    24         dfs(to[i],root);
    25         siz[x][root] += siz[to[i]][root];
    26     }
    27 }
    28 ll dfs2(int x,int y)
    29 {
    30     if (dp[x][y] != -1)
    31         return dp[x][y];
    32     return dp[x][y] = siz[x][y] * siz[y][x] + max(dfs2(x,fa[y][x]),dfs2(fa[x][y],y));
    33 }
    34 int main()
    35 {
    36     scanf("%d",&n);
    37     int tu,tv;
    38     for (int i = 1;i <= n - 1;i++)
    39     {
    40         scanf("%d%d",&tu,&tv);
    41         add(tu,tv);
    42         add(tv,tu); 
    43     }
    44     memset(dp,-1,sizeof(dp));
    45     for (int i = 1;i <= n;i++)
    46         dp[i][i] = 0;
    47     for (int i = 1;i <= n;i++)
    48         dfs(i,i);
    49     for (int i = 1;i <= n;i++)
    50         for (int j = 1;j <= n;j++)
    51             ans = max(ans,dfs2(i,j));
    52     printf("%lld
    ",ans);
    53     return 0;
    54 }
  • 相关阅读:
    ssm之spring+springmvc+mybatis整合初探
    mybatis缓存之整合第三方缓存工具ehcache
    mybatis缓存之二级缓存
    mybatis缓存之一级缓存
    mybatis动态sql之利用sql标签抽取可重用的sql片段
    mybatis动态sql之bind标签
    mybatis动态sql之内置参数_parameter和_databaseId
    mybatis动态sql之使用foreach进行批量插入的两种方式
    mybatis动态sql之foreach补充(三)
    Visitor Pattern
  • 原文地址:https://www.cnblogs.com/iat14/p/12290105.html
Copyright © 2020-2023  润新知