zoukankan      html  css  js  c++  java
  • 「考前日志」11.16

    总结

    最近状态不对劲

    今日已完成

    • 一节文化课:英语完形填空小技巧

      =_=这节课讲的东西还不如我自己的方法

    • AcWing287 积蓄程度
      换根DP,树形DP

      挺基础的换根DP了。随便找一个点作为根,记录每个点的度数,设 (f_x) 表示以 (x) 为根的子树,把 (x) 作为源点,从 (x) 出发流向子树的最大流量是多少,用 (du_x) 表示 (x) 的度数,有转移方程:

      [f_{x}=sumlimits_{toin{Son_{x}}}egin{cases}min(f_{to},val(x,to))& ext{if }du_{to}>1\val(x,to)& ext{if }du_{to}=1end{cases} ]

      之后考虑换根求出以每个点为根的答案,设 (g_x) 表示以 (x) 为整棵树的根所能流过的最大流量,因为每个 (x) 的儿子 (to) 都已经处理完了自身子树内的最大流量 (f_{to}),所以只需要处理 (x) 除了以 (to) 为根的子树之外的部分对 (g_{to}) 的贡献,那么有:

      [g_{to}=f_{to}+egin{cases}min(g_{x}-min({f_{to},val(x,to)}),val(x,to))& ext{if }du_{x}>1\val(x,to)& ext{if } du_{x}=1end{cases} ]

      发现是要自顶向下更新的,所以先更新,再进一步遍历。

      调了挺久发现是数组开小了= =

      #include <cmath>
      #include <queue>
      #include <cstdio>
      #include <vector>
      #include <cstring>
      #include <iostream>
      #include <algorithm>
      #define int long long
      using namespace std;
      
      const int A = 2e5 + 11;
      const int B = 1e6 + 11;
      const int mod = 1e9 + 7;
      const int inf = 0x3f3f3f3f;
      
      inline int read() {
        char c = getchar();
        int x = 0, f = 1;
        for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
        for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
        return x * f;
      }
      
      struct node { int to, nxt, val; } e[A << 1];
      int n, cnt, head[A], f[A], vis[A], g[A], du[A];
      
      inline void add(int from, int to, int val) {
        e[++cnt].to = to;
        e[cnt].val = val;
        e[cnt].nxt = head[from];
        head[from] = cnt;
      }
      
      inline void init() {
        cnt = 0;
        memset(f, 0, sizeof(f));
        memset(g, 0, sizeof(g));
        memset(du, 0, sizeof(du));
        memset(head, 0, sizeof(head));
      }
      
      void dfs(int x, int fa) {
        for (int i = head[x]; i; i = e[i].nxt) {
          int to = e[i].to;
          if (to == fa) continue;
          dfs(to, x);
          if (du[to] == 1) f[x] = f[x] + e[i].val;
          else f[x] = f[x] + min(e[i].val, f[to]);
        }
      }
      
      void change(int x, int fa) {
        for (int i = head[x]; i; i = e[i].nxt) {
          int to = e[i].to;
          if (to == fa) continue;
          if (du[x] == 1) g[to] = f[to] + e[i].val;
          else g[to] = f[to] + min(e[i].val, g[x] - min(f[to], e[i].val));
          change(to, x);
        }
      }
      
      inline void solve() {
        init();
        n = read();
        for (int i = 1; i < n; i++) {
          int x = read(), y = read(), val = read();
          du[x]++, du[y]++;
          add(x, y, val), add(y, x, val);
        }
        dfs(1, 0);
        g[1] = f[1];
        change(1, 0);
        int ans = 0;
        for (int i = 1; i <= n; i++) ans = max(ans, g[i]);
        cout << ans << '
      ';
        return;
      }
      
      signed main() {
        int T = read();
        while (T--) solve();
      }
      
    • 洛谷 P2018 消息传递

      树形DP,见此博客

      #include <cmath>
      #include <queue>
      #include <cstdio>
      #include <vector>
      #include <cstring>
      #include <iostream>
      #include <algorithm>
      using namespace std;
      
      const int A = 1e3 + 11;
      const int B = 1e6 + 11;
      const int mod = 1e9 + 7;
      const int inf = 0x3f3f3f3f;
      
      inline int read() {
        char c = getchar();
        int x = 0, f = 1;
        for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
        for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
        return x * f;
      }
      
      struct node { int to, nxt; } e[A << 1];
      int n, ans[A], f[A], head[A], cnt = 0, res = inf; 
      
      inline void add(int from, int to) {
        e[++cnt].to = to;
        e[cnt].nxt = head[from];
        head[from] = cnt;
      }
      
      bool cmp(int x, int y) {
        return x > y;
      }
      
      inline void dfs(int x, int fa) {
        int tot = 0, b[1000] = {0};
        for (int i = head[x]; i; i = e[i].nxt) {
          int to = e[i].to;
          if (to == fa) continue;
          dfs(to, x);
          b[++tot] = f[to];
        }
        sort(b + 1, b + 1 + tot, cmp);
        for (int i = 1; i <= tot; i++) 
          f[x] = max(f[x], b[i] + i);
      }
      
      int main() {
        n = read();
        for (int i = 2; i <= n; i++) {
          int x = read();
          add(x, i), add(i, x);
        }
        for (int i = 1; i <= n; i++) {
          memset(f, 0, sizeof(f));
          dfs(i, 0);
          res = min(f[i], res);
          ans[i] = f[i];
        }
        cout << res + 1 << '
      ';
        for (int i = 1; i <= n; i++) 
          if (ans[i] == res) cout << i << " ";
        puts("");
        return 0;
      }
      
    • AcWing288 休息时间

      环形DP问题的转化

      #include <cmath>
      #include <queue>
      #include <cstdio>
      #include <vector>
      #include <cstring>
      #include <iostream>
      #include <algorithm>
      using namespace std;
      
      const int A = 3831;
      const int B = 1e6 + 11;
      const int mod = 1e9 + 7;
      const int inf = 0x3f3f3f3f;
      
      inline int read() {
        char c = getchar();
        int x = 0, f = 1;
        for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
        for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
        return x * f;
      }
      
      int n, m, a[A], f[2][A][2], ans, now = 0, last = 1;
      
      int main() {
        n = read(), m = read();
        for (int i = 1; i <= n; i++) a[i] = read();
        memset(f, 0xcf, sizeof(f));
        f[now][0][0] = f[now][1][1] = 0;
        for (int i = 2; i <= n; i++) {
          swap(now, last);
          //debug:j从1开始枚举的 
          for (int j = 0; j <= m; j++) {
            f[now][j][0] = max(f[last][j][0], f[last][j][1]);
            if (j) f[now][j][1] = max(f[last][j - 1][0], f[last][j - 1][1] + a[i]);
          }
          memset(f[last], 0xcf, sizeof(f[last]));
        }
        ans = max(f[now][m][0], f[now][m][1]);
        memset(f, 0xcf, sizeof(f));
        f[now][1][1] = a[1], f[now][0][0] = 0;
        //忘记初始化f[now][0][0] 
        for (int i = 2; i <= n; i++) {
          swap(now, last);
          //debug:j从1开始枚举的
          for (int j = 0; j <= m; j++) {
            f[now][j][0] = max(f[last][j][0], f[last][j][1]);
            if (j) f[now][j][1] = max(f[last][j - 1][0], f[last][j - 1][1] + a[i]);
          }
          memset(f[last], 0xcf, sizeof(f[last]));
        }
        ans = max(ans, f[now][m][1]);
        cout << ans << '
      ';
        return 0;
      }
      
  • 相关阅读:
    一:多线程--多线程简单介绍
    五:网络--多线程断点下载
    四:网络--NSURLConnection基本使用
    三:网络--数据安全/加密
    二:网络--GET请求和POST请求
    一:网络--HTTP协议
    源代码管理工具GIT
    MyBatis 多参问题
    jquery 事件
    jquery点击事件
  • 原文地址:https://www.cnblogs.com/loceaner/p/13982707.html
Copyright © 2011-2022 走看看