zoukankan      html  css  js  c++  java
  • [刷题] 搜索剪枝技巧

    https://wenku.baidu.com/view/83b35f22aaea998fcc220e6a.html


    深度优先搜索问题的优化技巧
    提及:

    ZOJ1937

    IOI2000 BLOCK

    NOI2005 智慧珠

    USACO weight

    提交通道:weight

    Description

    已知原数列(a_1,a_2,dots,a_n)中的前(1)项,前(2)项,前(3)项,(dots),前(n)项的和,以及后(1)项,后(2)项,后(3)项,(dots),后(n)项的和,但是所有的数都被打乱了顺序。
    此外,我们还知道数列中的数存在于集合(S)中。试求原数列。
    当存在多组可能的数列时,求字典序最小的数列。
    数据范围 (1le nle1000,1le mle500) ,且 (S in{1,2,dots,500})

    Solution

    详情见文章和代码。

    Code

    // Author: wlzhouzhuan
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #include <bits/stdc++.h>
    using namespace std;
     
    #define ll long long
    #define ull unsigned long long
    #define rint register int
    #define rep(i, l, r) for (rint i = l; i <= r; i++)
    #define per(i, l, r) for (rint i = l; i >= r; i--)
    #define mset(s, _) memset(s, _, sizeof(s))
    #define pb push_back
    #define pii pair <int, int>
    #define mp(a, b) make_pair(a, b)
     
    inline int read() {
      int x = 0, neg = 1; char op = getchar();
      while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); }
      while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); }
      return neg * x;
    }
    inline void print(int x) {
      if (x < 0) { putchar('-'); x = -x; }
      if (x >= 10) print(x / 10);
      putchar(x % 10 + '0');
    }
    
    const int N = 20000005;
    int can[N], s[N], n, m;
    
    int a[N], b[N], lsum[N], rsum[N];
    void dfs(int k, int i, int j) { // 到s[k],已经确定a[1],a[2]...a[i]和a[j],a[j+1]....a[n] 
      if (i + 1 == j) {
        for (int p = i; p >= 1; p--) b[p] = a[p] - a[p - 1];
        for (int p = j; p <= n; p++) b[p] = a[p] - a[p + 1];
        for (int p = 1; p <= n; p++) lsum[p] = lsum[p - 1] + b[p];
        for (int p = n; p >= 1; p--) rsum[p] = rsum[p + 1] + b[p];
        /*printf("preout = 
    ");
        for (int p = 1; p <= n; p++) {
          printf("%d ", b[p]);
        } 
        puts("");
        */
        int le = n, ri = 1, tp = 2 * n;
        while (tp > n) {
          if (le > i && lsum[le] == s[tp]) le--;
          else if (ri < j && rsum[ri] == s[tp]) ri++;
          else return ;
          tp--;
        }
        for (int p = 1; p <= n; p++) {
          printf("%d ", b[p]);
        } 
        puts("");
        exit(0);
      }
      if (k >= n + 1) {
        return ;
      }
      if (s[k] - a[i] > 0 && s[k] - a[i] <= 500 && can[s[k] - a[i]]) {
        a[i + 1] = s[k];
        dfs(k + 1, i + 1, j);
        a[i + 1] = 0;
      }
      if (s[k] - a[j] > 0 && s[k] - a[j] <= 500 && can[s[k] - a[j]]) {
        a[j - 1] = s[k];
        dfs(k + 1, i, j - 1);
        a[j - 1] = 0;
      }
    }
    
    int main() {
      n = read();
      for (int i = 1; i <= 2 * n; i++) s[i] = read();
      sort(s + 1, s + 2 * n + 1);
      m = read();
      while (m--) {
        int x = read();
        can[x] = 1;
      }  
      dfs(1, 0, n + 1);
      return 0; 
    }
    
  • 相关阅读:
    不常用的cmd命令
    js获取宽度
    Marshaling Data with Platform Invoke 概览
    Calling a DLL Function 之三 How to: Implement Callback Functions
    Marshaling Data with Platform Invoke 之四 Marshaling Arrays of Types
    Marshaling Data with Platform Invoke 之一 Platform Invoke Data Types
    Marshaling Data with Platform Invoke 之三 Marshaling Classes, Structures, and Unions(用时查阅)
    Calling a DLL Function 之二 Callback Functions
    WCF 引论
    Marshaling Data with Platform Invoke 之二 Marshaling Strings (用时查阅)
  • 原文地址:https://www.cnblogs.com/wlzhouzhuan/p/12748195.html
Copyright © 2011-2022 走看看