zoukankan      html  css  js  c++  java
  • codeforces 338(Div 2) B. Longtail Hedgehog 解题报告

    题目链接:http://codeforces.com/problemset/problem/615/B

    题目意思:要画一只 hedgehog,由 tail 和 spines 组成。我们要求得 beauty 最大值: tail * spines。

    以下摘自 udon 原话,大家细细品味:(不一定是正确无误的哦,可能有误导他人成分。。。)

      1、对于所有点 x,求出 x 的度数 d[x],O(n+m)

      2、对于所有点 x,求出以点 x 为结尾的最长链长度 l[x],由于尾巴节点要求递增,符合DAG性质,从 1 点开始 BFS 就可以了,O(n+m)

      3、枚举所有 x,比较出 l[x] * d[x] 最大值,得出答案, O(n),总复杂度O(n+m)

      spines其实就是tail最后一个点的度数,也就是tail确定之后,spines就自然出来了(spines等价于度数)

      这句话主要是给我看的:我们不是要spines最优(我之前一直被这个变量迷惑了= =),而是要 tail * spines 最优

      以下也是他的话:

    ############################  听udon一席话,胜读十年书呢 ^_^

    分享下捻尼题既思路,其实就系物理常用控制变量法:
    1、发现最后答案 res = max(tails * spines),有两个变量
    2、简化下问题,我先假设spines一定的情况下,答案貌似就系tails最大值,已经系经典题目了
    但系甘样要枚举所有度数下的tails最优值,超时
    3、我再假设tails不变,情况下,根据定义spines就系tails最后一个点既度数数,嗟系
    tails可以确定spines,唔洗求最优值!!
    4、甘样我地久唔洗枚举度数,枚举tails就可以了

    #############################

    (1) DP 版本

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <vector>
     7 using namespace std;
     8 
     9 typedef long long LL;
    10 
    11 const int maxn = 1e5 + 5;
    12 vector<int> edge[maxn];
    13 LL dp[maxn];
    14 
    15 int main()
    16 {
    17     #ifndef ONLINE_JUDGE
    18         freopen("in.txt", "r", stdin);
    19     #endif // ONLINE_JUDGE
    20 
    21     int n, m;
    22     while (scanf("%d%d", &n, &m) != EOF) {
    23 
    24         int u, v;
    25         for (int i = 0; i < m; i++) {
    26             scanf("%d%d", &u, &v);
    27             edge[u].push_back(v);
    28             edge[v].push_back(u);
    29         }
    30         LL ans = -1;
    31         for (int i = 1; i <= n; i++) {
    32             dp[i] = 1;
    33             sort(edge[i].begin(), edge[i].end());
    34             for (int j = 0; j < edge[i].size(); j++) {
    35                 if (edge[i][j] > i) continue;
    36                 dp[i] = max(dp[i], dp[edge[i][j]]+1);
    37             }
    38             ans = max(ans, dp[i]*(int)edge[i].size());
    39         }
    40         printf("%lld
    ", ans);
    41         for (int i = 1; i <= n; i++) {
    42             edge[i].clear();
    43         }
    44     }
    45 
    46     return 0;
    47 }

    (2)DFS版本(记忆化搜索)

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <vector>
     7 using namespace std;
     8 
     9 typedef long long LL;
    10 
    11 const int maxn = 1e5 + 5;
    12 vector<int> edge[maxn];
    13 int vis[maxn];
    14 LL ans;
    15 
    16 int dfs(int st)
    17 {
    18     if (vis[st])
    19         return vis[st];   // 记忆化搜索,避免超时
    20     int ret = 0;    // 设为-1是错的,因为 st 编号的数可能前面根本没有比它小的数 
    21     for (int i = 0; i < edge[st].size(); i++) {
    22         if (edge[st][i] < st) {  // 求出以 st 之前的最长递增序列
    23             ret = max(ret, dfs(edge[st][i]));
    24         }
    25     }
    26     vis[st] = ret + 1;
    27     return vis[st];
    28 }
    29 
    30 
    31 int main()
    32 {
    33     #ifndef ONLINE_JUDGE
    34         freopen("in.txt", "r", stdin);
    35     #endif // ONLINE_JUDGE
    36 
    37     int n, m;
    38     while (scanf("%d%d", &n, &m) != EOF) {
    39 
    40         int u, v;
    41         for (int i = 0; i < m; i++) {
    42             scanf("%d%d", &u, &v);
    43             edge[u].push_back(v);
    44             edge[v].push_back(u);
    45         }
    46         memset(vis, 0, sizeof(vis));
    47         ans = -1;
    48         for (int i = 1; i <= n; i++) {
    49             if (!vis[i]) {
    50                 ans = max( ans, (LL)dfs(i)*(int)edge[i].size() );
    51             }
    52         }
    53 
    54         printf("%lld
    ", ans);
    55         for (int i = 1; i <= n; i++) {
    56             edge[i].clear();
    57         }
    58     }
    59 
    60     return 0;
    61 }
  • 相关阅读:
    嵌入式linux调试技术
    HAL
    让开发板发出声音: 蜂鸣器驱动
    LED 将为我闪烁: 控帘 j发光二级管
    第一个Linux驱动程序: 统计单词个数
    搭建 S3C6.410 开发板的 测试环境
    第四章源代码的下载和编译读后感
    第三章Git使用入门读后感
    第二章搭建安卓开发环境读后感
    第一章安卓系统移植和驱动开发读后感
  • 原文地址:https://www.cnblogs.com/windysai/p/5118700.html
Copyright © 2011-2022 走看看