zoukankan      html  css  js  c++  java
  • 搜索Ex

    哎呀好几天没写POI题解了 (>﹏<)

    看着摇曳不定的小旗子深深惶恐

    打算开始肝洛谷试炼场的提高分区了【对我就是这么菜…

    • 搜索Ex

    比暴搜不错得多的题

    洛谷P1514 引水入城

    拆成两问来看 第一问只要从湖边的城市(简称湖城)开始搜索就可以了

    第二问的faulse项

    用dfs剩的vis统计一下沙漠边缘有哪些点(简称沙城)没被搜到的

    true项 蒟蒻一开始想状压

    当然 n <= 500 【黑线

    后来画了个等高线地形图【划掉

    发现如果每个沙城都能有水喝【即true项

    每个湖城管辖的沙城都是连续的区间

    现在问题就变成了 至少用多少个区间覆盖整个区间

    当然这问题长得很DP 但有个贪心更优

    借用一位神犇的例子

    m为10
    N = 7:[1,5]、[1,6]、[3,6]、[1,7]、[6,9]、[9,10]、[7,9]。

    先把每个区间(都是闭区间)排序 左区间小的优先

    [1,5]、[1,6]、[1,7]、[3,6]、[6,9]、[7,9]、[9,10]

    我们从1开始

    选择每个区间的代价都是1 选择右区间大的显然更优

    所以取[1, 7]

    现在左区间小区等于7的区间 在小于等于7的部分已经被覆盖 所以无效了

    为使区间连续 我们找(左区间小于等于8的区间)中(右区间最大的区间)

    okk

    最后附一句 如果找到一个地方 (可用最大右区间)小于(上一个取的区间的左区间)

     1 inline void dfs(int x, int y){
     2      node[x][y].vis = 1;
     3      if(x < 1 || x > n || y < 1 || y > m) return ;
     4      for(int i = 0; i <= 3; i++){
     5          int sx = x + move[i][0], sy = y + move[i][1];
     6          if(node[sx][sy].w < node[x][y].w){
     7              if(!node[sx][sy].vis){
     8                  dfs(sx, sy);                              
     9              }        
    10              node[x][y].l = min(node[sx][sy].l, node[x][y].l);
    11              node[x][y].r = max(node[sx][sy].r, node[x][y].r);
    12          }         
    13      }
    14 }
    dfs部分
     1     for(int i = 1; i <= m; i++)
     2        a[i] = (A){node[1][i].l, node[1][i].r};
     3     sort(a + 1, a + m + 1, cmp);
     4     int i = 1, j = 1, ans = 0;
     5     while(j <= m){
     6         int k = j;
     7         while(a[i].l <= k){
     8             j = max(j, a[i].r);
     9             i++;             
    10         }
    11         j++;        
    12         ans++;
    13     }
    14     printf("1
    %d", ans);
    贪心部分

    洛谷P1242 新汉诺塔

    吐槽玄学数据…

    明明能一次A的wwww【委屈

     1 void dfs(int cur, int from, int to, bool flag){
     2      //cur表示当前要移动的圆盘大小 from表示它在的位置 to表示它要移动到的地方 
     3      //flag = 1 表示cur是在进行主操作的点 flag = 0表示cur是为了移动另一个圆盘而移动的 
     4     if(from == to){
     5         if(cur > 1) dfs(cur - 1, s[cur - 1], flag ? t[cur - 1] : to, flag);
     6         /*
     7         当要移动的盘已经在它的目标位置上
     8         如果flag = 1 那么它的主操作已经被完成 需要将主操作传递到下一个级别的圆盘上 
     9         flag = 0 那么要把下一个级别的圆盘从它的位置上移动到无关的杆子上 
    10         */
    11         return ;        
    12     }     
    13     if(cur > 1) dfs(cur - 1, s[cur - 1], 6 - from - to, 0); 
    14     //把比它小的所有盘都移到无关的杆子上 
    15     printf("move %d from %c to %c
    ", cur, turn(from), turn(to));
    16     s[cur] = to; ans++;
    17     //移动后 当前盘已经在目标位置上 与from == to的操作一致 
    18     if(cur > 1) dfs(cur - 1, s[cur - 1], flag ? t[cur - 1] : to, flag);
    19 }
    20 /*
    21 汉诺塔的框架:
    22 将主操作从大盘向小盘传递 
    23 移动一个盘的最优策略是把它上面的盘都移到无关杆上
    24 注意的点:
    25 flag的传递
    26 起点终点的选择
    27 输出格式
    28 结束条件(cur == 1) 
    29 */ 

    P1120 小木棍 [数据加强版]

    啊啊啊QAQ 都是泪

    有个剪枝不错

                if ( sum == 0 || sum + i == target )  //4
                    break;


     

     

  • 相关阅读:
    BFS POJ 2251 Dungeon Master
    DFS POJ 1321 棋盘问题
    构造 Codeforces Round #275 (Div. 2) C. Diverse Permutation
    线段树+树状数组+贪心 HDOJ 5338 ZZX and Permutations
    快速幂取模 POJ 3761 bubble sort
    矩阵快速幂 POJ 3070 Fibonacci
    矩阵快速幂 POJ 3735 Training little cats
    DP+矩阵快速幂 HDOJ 5318 The Goddess Of The Moon
    L2-001. 紧急救援(PAT)~最短路应用
    ~psd面试 求最长回文序列 DP求解
  • 原文地址:https://www.cnblogs.com/hjmmm/p/9207829.html
Copyright © 2011-2022 走看看