zoukankan      html  css  js  c++  java
  • bupt summer training for 16 #7 ——搜索与DP

    https://vjudge.net/contest/174962#overview

    A.我们发现重点在于x,y只要累加就ok了

    在每个x上只有上下两种状态,所以可以记忆化搜索

    f[0/1][i]表示 x = i 时向下/上走,那需要移动多少才能走出去

     1 #include <cstdio>
     2 #include <algorithm>
     3 
     4 using namespace std;
     5 
     6 const int maxn = 500010;
     7 
     8 typedef long long ll;
     9 
    10 ll a[maxn], f[2][maxn];
    11 
    12 int n, b[2][maxn], vis[2][maxn];
    13 
    14 ll dfs(int i, int k, ll d = 0) {
    15     if(vis[k][i]) {
    16         b[k][i] = -1;
    17         return f[k][i] = 0;
    18     }
    19     vis[k][i] = 1;
    20     if(!f[k][i]) {
    21         int y = i + (k ? a[i] : -a[i]);
    22         if(y > n || y <= 1) d = 0;
    23         else d = dfs(y, k ^ 1);
    24         f[k][i] = d + a[i];
    25         if(y >= 1 && y <= n && b[k ^ 1][y]) b[k][i] = -1;
    26     }
    27     vis[k][i] = 0;
    28     return f[k][i];
    29 }
    30 
    31 int main() {
    32     scanf("%d", &n);
    33     for(int i = 2;i <= n;i ++)
    34         scanf("%I64d", &a[i]);
    35     b[0][1] = b[1][1] = -1;
    36     for(int i = 2;i <= n;i ++)
    37         dfs(i, 0), dfs(i, 1);
    38     for(int i = 1;i < n;i ++) {
    39         if(b[0][1 + i]) puts("-1");
    40         else printf("%I64d
    ", i + f[0][1 + i]);
    41     }
    42     return 0;
    43 }
    View Code

    写狗了又RE又T又WA的...写的丑陋,我。无法忍受

    B.非常无脑的爆搜,效率玄学

    数据范围个位数还是可以大胆以下的

     1 #include <cstdio>
     2 #include <algorithm>
     3 
     4 using namespace std;
     5 
     6 const int xx[] = {-1, 1, 0, 0};
     7 const int yy[] = {0, 0, 1, -1};
     8 
     9 int n, m, k;
    10 
    11 char s[10][10];
    12 
    13 bool vis[10][10];
    14 
    15 bool dfs(const int &x, const int &y, const int &cc) {
    16     if(cc == k) return 1;
    17     int nx, ny;
    18     for(int i = 0;i < 4;i ++) {
    19         nx = x + xx[i], ny = y + yy[i];
    20         if(nx > 0 && nx <= n && ny > 0 && ny <= m && s[nx][ny] != 'S' && !vis[nx][ny]) {
    21             vis[nx][ny] = 1;
    22             if(dfs(nx, ny, cc + 1)) return 1;
    23             vis[nx][ny] = 0;
    24         }
    25     }
    26     return 0;
    27 }
    28 
    29 int main() {
    30     while(scanf("%d %d", &n, &m), n!= 0) {
    31         k = 0;
    32         for(int i = 1;i <= n;i ++) {
    33             scanf("%s", s[i] + 1);
    34             for(int j = 1;j <= m;j ++)
    35                 vis[i][j] = 0, k += (s[i][j] != 'S');
    36         }
    37         vis[1][1] = 1;
    38         puts(dfs(1, 1, 1) ? "YES" : "NO");
    39     }
    40     return 0;
    41 }
    View Code

    C.显而易见的树型DP,依旧写的很糟...

    f[i][j]表示从节点 i 向下走距离 j 能获得的最大价值

     1 #include <cstdio>
     2 #include <vector>
     3 #include <cstring>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 int n, m, s, a[110], f[110][110], g[110][110];
     9 
    10 vector <pair<int,int> > e[110];
    11 
    12 void dfs(int u, int fa) {
    13     int v, w, i;
    14     for(i = 0;i <= m;i ++) g[u][i] = 0;
    15     for(i = 0;i < e[u].size();i ++) {
    16         v = e[u][i].first;
    17         if(v == fa) continue;
    18         w = e[u][i].second;
    19         dfs(v, u);
    20         for(int j = m;j >= 0;j --)
    21             for(int k = j;k >= 0;k --)
    22                 if(j - k - w >= 0) 
    23                     f[u][j] = max(f[u][j], g[u][k] + f[v][j - k - w]);
    24         for(int j = 0;j <= m;j ++)
    25             g[u][j] = f[u][j];
    26     }
    27     for(i = 0;i <= m;i ++) f[u][i] += a[u];
    28 }
    29 
    30 int main() {
    31     while(~scanf("%d", &n)) {
    32         memset(f, 0, sizeof f);
    33         memset(g, 0, sizeof g);
    34         memset(e, 0, sizeof e);
    35         for(int i = 1;i <= n;i ++)
    36             scanf("%d", &a[i]);
    37         for(int u, v, w, i = 1;i < n;i ++) {
    38             scanf("%d %d %d", &u, &v, &w);
    39             e[u].push_back(make_pair(v, w));
    40             e[v].push_back(make_pair(u, w));
    41         }
    42         scanf("%d %d", &s, &m), m /= 2;
    43         dfs(s, s);
    44         printf("%d
    ", f[s][m]);
    45     }
    46     return 0;
    47 }
    View Code

    D.大家都会写大龙虾算法让我有些惶恐...

    于是决定抄一发队友的dlx板子

  • 相关阅读:
    基于Cat的分布式调用追踪
    python3.8.0 Django 开发后端接口api 部署到 Linux Centos7上
    openlayers上添加点击事件
    openlayers在底图上添加静态icon
    vue中使用kindeditor富文本编辑器2
    openlayers绘制点,线,圆等
    openLayers绘制静态底图
    快速调用Android虚拟机
    flutter环境配置window10
    reactjs中配置代理跨域
  • 原文地址:https://www.cnblogs.com/ytytzzz/p/7265837.html
Copyright © 2011-2022 走看看