zoukankan      html  css  js  c++  java
  • 抽签问题(不断优化)

    问题描述:

    假设存在n个签,通过抽取四次,如果四次抽取的和为m即胜利。

    初始解:

     1 for(int a = 0; a < n; a++)
     2 {
     3     for(int b = 0; b < n; b++)
     4     {
     5         for(int c = 0; c < n; c++)
     6         {
     7             for(int d = 0; d < n; d++)
     8             {
     9                 if(k[a] + k[b] + k[c] + k[d] == m)
    10                     f = true;
    11             }
    12         }
    13     }
    14 }

    难度增加,将n的限制条件为1~1000,此时,四重循环明显复杂度过高,需改进算法。

    上面所记载的程序的循环部分。最内侧关于d的循环所做的事就是

    检查是否有d使得

    通过对式子移项,就能得到另一种表达式

    检查是否有d使得

    就是说,检查数组k中所有元素,判断是否有

    结合二分搜索进行求解,注意二分搜索前提为该数组排好序(可用c++自带的binary_serach)

     1 int n, m, k[MAX_N];
     2 
     3 bool binary_serach(int x)
     4 {
     5     int l = 0, r = n;
     6     while(r - 1 >= 1)
     7     {
     8         int i = (l + r) / 2;
     9         if(k[i] == x)
    10             return true;
    11         else if(k[i] < x)
    12             l = i + 1;
    13         else
    14             r = i;
    15     }
    16     return false;
    17 }
    18 
    19 void solve()
    20 {
    21     sort(k, k + n);
    22     bool f = false;
    23     for(int a = 0; a < n; a++)
    24     {
    25         for(int b = 0; b < n; b++)
    26         {
    27             for(int c = 0; c < n; c++)
    28             {
    29                 if(binary_serach(m - k[a] - k[b] - k[c]))
    30                 {
    31                     f = true;
    32                 }
    33             }
    34         }
    35     }
    36     if(f)
    37         cout << "Yes" << endl;
    38     else
    39         cout << "No" << endl;
    40 }

     的算法

    着眼于内层的两个循环

    检查是否有c和d使得

    这种情况并不能直接使用二分搜索。但是,如果预先枚举出所得的个数字并排好序,便可以利用二分搜索了。

     1 int n, m, k[MAX_N];
     2 int kk[MAX_N * MAX_N];
     3 bool binary_serach(int x)
     4 {
     5     int l = 0, r = n * n;
     6     while(r - 1 >= 1)
     7     {
     8         int i = (l + r) / 2;
     9         if(kk[i] == x)
    10             return true;
    11         else if(kk[i] < x)
    12             l = i + 1;
    13         else
    14             r = i;
    15     }
    16     return false;
    17 }
    18 
    19 void solve()
    20 {
    21     for(int c = 0; c < n; c++)
    22     {
    23         for(int d = 0; d < n; d++)
    24         {
    25             kk[c * n + d] = k[c] + k[d];
    26         }
    27     }
    28     
    29     sort(kk, kk + n * n);
    30     for(int a = 0; a < n; a++)
    31     {
    32         for(int b = 0; b < n; b++)
    33         {
    34             if(binary_serach(m - k[a] - k[b]))
    35             {
    36                 f = true;
    37             }
    38         }
    39     }
    40     if(f)
    41         cout << "Yes" << endl;
    42     else
    43         cout << "No" << endl;
    44 }
  • 相关阅读:
    你知道怎么离线安装全局 node 模块吗?
    关于开发视图
    你知道 JavaScript 中的 Arguments 对象都有哪些用途吗?
    前端 JavaScript 实现一个简易计算器
    Docker 系列 _ 01_ 一念缘起
    机器学习资料大全
    pdf、txt文本复制到EXCEL后的格式快速调整法
    习惯的养成
    磁盘剩余空间监控
    please wait while windows configures microsoft visual studio professional 2013
  • 原文地址:https://www.cnblogs.com/CZT-TS/p/8370635.html
Copyright © 2011-2022 走看看