首页 > 其他分享 >多重背包详解,二进制优化、单调队列优化

多重背包详解,二进制优化、单调队列优化

时间:2024-03-13 15:00:49浏览次数:19  
标签:10 ch 背包 二进制 int 详解 3.1 include 优化

文章目录


零、前言

多重背包问题,和01背包、完全背包问题相比,实就是每个物品可以取的数目是限定的。它是01背包和完全背包的一般性问题。

一、多重背包初步

1.1问题描述

有n种物品和一个容量为m的背包。第i种物品最多有s件,每件体积是ci,价值是wi。求解选择哪些物品放入背包,使物品体积总和不超过背包容量,且价值总和最大。只输出最大价值。

1.2朴素算法

01背包:第 i 种物品取0件、1件。

多重背包:第 i 种物品取0、1、……、si件

如果我们把第i种物品拆成si件物品,然后当作01背包问题去求解,我们发现是可以得到正确解的。

在01背包的板子上稍加修改即可

// c[i],w[i],s[i];体积、价值、数目
for (int i = 1; i <= n; i++)
    for (int j = m; j >= c[i]; j--)
        for (int k = 0; k <= s[i] && k * c[i] <= j; k++)
            f[j] = max(f[j], f[j - k * c[i]] + w[i] * k);

时间复杂度:O(mΣsi)

当我们有n,m,si <= 1000时,时间复杂度就能达到1e9量级,显然会超时,那么如何优化呢?

二、朴素算法的优化策略

2.1二进制优化

2.1.1算法思想

二进制拆分的思想我们在很多算法或者数据结构中都有涉及,如倍增算法、树状数组等。

朴素算法是把一件物品拆成了si件单独的物品,这样做太浪费了,二进制优化也是拆分物品,不过是这样拆的:

将第 i 件物品拆成20、21、22、……、2(k - 1)、si - 2^k + 1件物品,其价值和体积为单件价值/体积乘数量,然后也按照01背包做法去求解。

但是,朴素算法把一件拆成si件然后按照01背包去求解是正确的是因为其能够计算出每件物品去0~si件的情况,那么我们二进制拆分是否也能如此呢?

2.2二进制优化的正确性证明

对于20、21、22、……、2(k - 1)、si - 2^k + 1

对于前k项,可以组合出[0, 2^k - 1]内的数字,然后加上第k + 1项也就是si - 2^k + 1后,又能表示出[si - 2^k + 1, si]内的数字

故二进制优化可以考虑到原问题的所有情况。

2.3代码实现

时间复杂度:O(mΣlogsi),当有n,m,si <= 1000时,算法在1e7量级,是可以过的

//int f[N], n, m, c[N], w[N], tot = 0;
for (int i = 1, C, W, S; i <= n; i++)
{
    cin >> C >> W >> S;//第i件物品的体积,价值,数目
    for (int j = 1; j <= S; j <<= 1)
        ++tot, c[tot] = j * C, w[tot] = j * C, S -= j;
    if (S)
        ++tot, c[tot] = S, w[tot] = s * W;
}
for (int i = 1; i <= tot; i++)//01背包板子
    for (int j = m; j >= c[i]; j--)
        f[j] = max(f[j], f[j - c[i]] + w[i]);

2.2单调队列优化

2.2.1算法思想

回看朴素算法代码

// c[i],w[i],s[i];体积、价值、数目
for (int i = 1; i <= n; i++)
    for (int j = m; j >= c[i]; j--)
        for (int k = 0; k <= s[i] && k * c[i] <= j; k++)
            f[j] = max(f[j], f[j - k * c[i]] + w[i] * k);

f[j] = max(f[j], f[j - c[i]] + w[i], f[j - 2*c[i]] + 2*w[i], …, f[j - k * c[i]] + w[i] * k)

我们发现对于第 i 件物品而言,f(i, j)的可转移前驱状态f(i - 1, k)都满足k 和 j对c[i]的余数相同

那么我们可以将原本的f[0 … m]简化为f[0, 1, …, c[i] - 1],即按对c[i]的余数将状态分类:

f[0]、f[c[i]]……f[kc[i]]

f[1]、f[1 + c[i]]……f[1 + kc[i]]

……

f[c[i] - 1]、f[2*c[i] - 1]……f[(k + 1)c[i] - 1]

f[j]是由前面不超过数量s的同类值递推得到的。这就相当于从前面宽度为s的窗口挑选最大值来更新当前值。所以,我们用单调队列来维护窗口最大值,这样**每次获取窗口最大值是均摊O(1)**的。

这就需要顺序更新f值,怎么办呢?只需要增加一个备份数组g即可。

2.2.2代码实现

时间复杂度:O(n C m/C) = O(nm)**

for (int i = 1, C, W, S; i <= n; i++)
{
    memcpy(g, f, sizeof f), cin >> C >> W >> S;//体积、价值、数目
    for (int j = 0; j < C; j++)
    {
        h = t = 0;
        for (int k = j; k <= m; k += C)
        {
            if (t - h && q[h] < k - S * C)//队头不在区间[k - S*C, k - C]内
                h++;
            if (t - h)
                f[k] = max(f[k], g[q[h]] + (k - q[h]) / C * W);//状态转移
            while (t - h && g[k] >= g[q[t - 1]] + (k - q[t - 1]) / C * W)//维护单调队列队头到队尾单调递减
                t--;
            q[t++] = k;
        }
    }
}

2.3、总结

两种优化方法都应用了拆分思想

二进制优化拆分的是物品数量si,si件拆分成logsi件

单调队列优化拆分的是背包容量m根据v的余数,把f[0…m]拆分成c个类,使f[0…m] 在0(m)内完成更新。

三、OJ练习

3.1P1776 宝物筛选

3.1.1原题链接

P1776 宝物筛选 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

3.1.2思路分析

板子题,直接跑板子

3.1.3AC代码
3.1.3.1二进制优化
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 1010, M = 1e5 + 10;
int f[M], q[M], c[M], w[M], n, m, tot;

signed main()
{
    //freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for (int i = 1, C, W, S; i <= n; i++)
    {
        cin >> W >> C >> S;
        for (int j = 1; j <= S; j <<= 1)
            ++tot, c[tot] = j * C, w[tot] = j * W, S -= j;
        if (S)
            ++tot, c[tot] = S * C, w[tot] = S * W;
    }
    for (int i = 1; i <= tot; i++)
        for (int j = m; j >= c[i]; j--)
            f[j] = max(f[j], f[j - c[i]] + w[i]);
    cout << f[m];
    return 0;
}

3.1.3.1单调队列优化
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 1010, M = 1e5 + 10;
int f[M], g[M], q[M], n, m, h, t;

signed main()
{
    //freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for (int i = 1, c, w, s; i <= n; i++)
    {
        memcpy(g, f, sizeof f), cin >> w >> c >> s;
        for (int j = 0; j < c; j++)
        {
            h = t = 0;
            for (int k = j; k <= m; k += c)
            {
                if (t - h && q[h] < k - c * s)
                    h++;
                if (t - h)
                    f[k] = max(g[k], g[q[h]] + (k - q[h]) / c * w);
                while (t - h && g[k] >= g[q[t - 1]] + (k - q[t - 1]) / c * w)
                    t--;
                q[t++] = k;
            }
        }
    }
    cout << f[m];
    return 0;
}

3.2P1782 旅行商的背包

3.2.1原题链接

P1782 旅行商的背包 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

3.2.2思路分析

对于前n个物品我们当作多重背包去解

然后后m个奇货,枚举体积当01背包做就行,由于m最大也就5,时间复杂度完全可以

3.2.3AC代码
3.2.3.1二进制优化
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
int read()
{
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            w *= -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        s = (s << 3) + (s << 1) + (ch ^ 48);
        ch = getchar();
    }
    return s * w;
}
void write(int x)
{
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        write(x / 10);
    putchar((x % 10) ^ 48);
}
const int N = 1e4 + 10, M = 1e4 + 10;
int f[M], c[N * 10], w[N * 10], n, m, V, tot;
signed main()
{
    //freopen("in.txt", "r", stdin);
    n = read(), m = read(), V = read();
    for (int i = 1, C, W, S; i <= n; i++)
    {
        C = read(), W = read(), S = read();
        for (int j = 1; j <= S; j <<= 1)
            c[++tot] = C * j, w[tot] = W * j, S -= j;
        if (S)
            c[++tot] = C * S, w[tot] = W * S;
    }
    for (int i = 1; i <= tot; i++)
        for (int j = V; j >= c[i]; j--)
            f[j] = max(f[j], f[j - c[i]] + w[i]);
    for (int i = 1, x, y, z; i <= m; i++)
    {
        x = read(), y = read(), z = read();
        for (int j = V; j; j--)
            for (int k = 0; k <= j; k++)
                f[j] = max(f[j], f[j - k] + (x * k + y) * k + z);
    }
    write(f[V]);
    return 0;
}
3.2.3.1单调队列优化
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
int read()
{
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            w *= -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        s = (s << 3) + (s << 1) + (ch ^ 48);
        ch = getchar();
    }
    return s * w;
}
void write(int x)
{
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        write(x / 10);
    putchar((x % 10) ^ 48);
}
const int N = 1e4 + 10, M = 1e4 + 10;
int f[M], g[M], q[N * 10], n, m, V, h, t;
signed main()
{
    //freopen("in.txt", "r", stdin);
    n = read(), m = read(), V = read();
    for (int i = 1, C, W, S; i <= n; i++)
    {
        C = read(), W = read(), S = read(), memcpy(g, f, sizeof f);
        for (int j = 0; j < C; j++)
        {
            h = t = 0;
            for (int k = j; k <= V; k += C)
            {
                while (t - h && q[h] < k - S * C)
                    h++;
                if (t - h)
                    f[k] = max(g[k], g[q[h]] + (k - q[h]) / C * W);
                if (t - h && g[k] >= g[q[t - 1]] + (k - q[t - 1]) / C * W)
                    t--;
                q[t++] = k;
            }
        }
    }
    for (int i = 1, x, y, z; i <= m; i++)
    {
        x = read(), y = read(), z = read();
        for (int j = V; j; j--)
            for (int k = 0; k <= j; k++)
                f[j] = max(f[j], f[j - k] + (x * k + y) * k + z);
    }
    write(f[V]);
    return 0;
}

3.3Dividing

3.3.1原题链接

Problem - 1059 (hdu.edu.cn)

3.3.2思路分析

背包求解可行性问题

挺无脑的,我们把价值当作体积,价值当作价值(我在说什么=-=

这俩哥们给大理石附加的value我们当作价值也当作体积,然后背包体积当作价值的二分之一,看这个包能不能装满就行

然后就是跑板子,没啥思维难度

3.3.3AC代码
3.3.3.1二进制优化
#include <iostream>
#include <cstring>
#include <algorithm>
#include <numeric>
using namespace std;
#define int long long
int f[6 * 20000 + 10], c[20000 * 500], w[20000 * 500], tot;
int s[7], m, _ = 0;
signed main()
{
    //freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    while (cin >> s[1] >> s[2] >> s[3] >> s[4] >> s[5] >> s[6], s[1] || s[2] || s[3] || s[4] || s[5] || s[6])
    {
        tot = 0, m = s[1] + s[2] * 2 + s[3] * 3 + s[4] * 4 + s[5] * 5 + s[6] * 6;
        if (m & 1)
        {
            cout << "Collection #" << ++_ << ":\n"
                 << "Can't be divided.\n";
            continue;
        }
        m >>= 1, memset(f, 0, sizeof f);
        for (int i = 1; i <= 6; i++)
        {
            for (int j = 1; j <= s[i]; j <<= 1)
                c[++tot] = i * j, w[tot] = i * j, s[i] -= j;
            if (s[i])
                c[++tot] = i * s[i], w[tot] = i * s[i];
        }
        for (int i = 1; i <= tot; i++)
            for (int j = m; j >= c[i]; j--)
                f[j] = max(f[j], f[j - c[i]] + w[i]);
        if (f[m] == m)
            cout << "Collection #" << ++_ << ":\n"
                 << "Can be divided.\n";
        else
            cout << "Collection #" << ++_ << ":\n"
                 << "Can't be divided.\n";
    }
    return 0;
}
3.3.3.2单调队列优化
#include <iostream>
#include <cstring>
#include <algorithm>
#include <numeric>
using namespace std;
#define int long long
int f[6 * 20000 + 10], g[6 * 20000 + 10], q[6 * 20000 + 10], h, t;
int s[7], m, _ = 0;
signed main()
{
    //freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    while (cin >> s[1] >> s[2] >> s[3] >> s[4] >> s[5] >> s[6], s[1] || s[2] || s[3] || s[4] || s[5] || s[6])
    {
        m = s[1] + s[2] * 2 + s[3] * 3 + s[4] * 4 + s[5] * 5 + s[6] * 6;
        if (m & 1)
        {
            cout << "Collection #" << ++_ << ":\n"
                 << "Can't be divided.\n\n";
            continue;
        }
        m >>= 1, memset(f, 0, sizeof f);
        for (int i = 1; i <= 6; i++)
        {
            memcpy(g, f, sizeof f);
            for (int j = 0; j < i; j++)
            {
                h = t = 0;
                for (int k = j; k <= m; k += i)
                {
                    if (t - h && q[h] < k - s[i] * i)
                        h++;
                    if (t - h)
                        f[k] = max(g[k], g[q[h]] + (k - q[h]) / i * i);
                    while (t - h && g[k] >= g[q[t - 1]] + (k - q[t - 1]) / i * i)
                        t--;
                    q[t++] = k;
                }
            }
        }
        if (f[m] == m)
            cout << "Collection #" << ++_ << ":\n"
                 << "Can be divided.\n\n";
        else
            cout << "Collection #" << ++_ << ":\n"
                 << "Can't be divided.\n\n";
    }
    return 0;
}

3.4Coins

3.4.1原题链接

Problem - 2844 (hdu.edu.cn)

3.4.2思路分析

同样是背包解决可行性问题

在本题中背包体积就是m,物体体积就是物体的价值,跑完背包板子从1遍历到m看看可行的状态有多少就行

3.4.3AC代码
3.4.3.1二进制优化
#include <iostream>
#include <cstring>
#include <algorithm>
#include <numeric>
using namespace std;
#define int long long
const int N = 110, M = 100000 + 10;
int n, m, c[N * 10], A[N], tot, ret;
bool f[M];
signed main()
{
    //freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    while (cin >> n >> m, n)
    {
        memset(f, 0, sizeof f), tot = ret = 0;
        for (int i = 1; i <= n; i++)
            cin >> A[i];
        for (int i = 1, S; i <= n; i++)
        {
            cin >> S;
            for (int j = 1; j <= S; j <<= 1)
                c[++tot] = A[i] * j, S -= j;
            if (S)
                c[++tot] = A[i] * S;
        }
        f[0] = 1;
        for (int i = 1; i <= tot; i++)
            for (int j = m; j >= c[i]; j--)
                f[j] = f[j] || f[j - c[i]];
        for (int i = 1; i <= m; i++)
            ret += f[i];
        cout << ret << '\n';
    }
    return 0;
}
3.4.3.2单调队列优化
#include <iostream>
#include <cstring>
#include <algorithm>
#include <numeric>
using namespace std;
#define int long long
const int N = 110, M = 100000 + 10;
int n, m, q[N * 10], h, t, A[N], ret;
bool f[M], g[M];
signed main()
{
    //freopen("in.txt", "r", stdin);
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    while (cin >> n >> m, n)
    {
        memset(f, 0, sizeof f), ret = 0;
        for (int i = 1; i <= n; i++)
            cin >> A[i];
        f[0] = 1;
        for (int i = 1, s; i <= n; i++)
        {
            cin >> s, memcpy(g, f, sizeof f);
            for (int j = 0; j < A[i]; j++)
            {
                h = t = 0;
                for (int k = j; k <= m; k += A[i])
                {
                    while (t - h && q[h] < k - s * A[i])
                        h++;
                    if (t - h)
                        f[k] = g[k] || g[q[h]];
                    while (t - h && g[k] >= g[q[t - 1]])
                        t--;
                    q[t++] = k;
                }
            }
        }
        for (int i = 1; i <= m; i++)
            ret += f[i];
        cout << ret << '\n';
    }
    return 0;
}

3.5Cash Machine

3.5.1原题链接

1276 – Cash Machine (poj.org)(男人八题!)

3.5.2思路分析

也是可行性问题

背包体积即cash,然后物体的体积就是钱的面额,然后就是跑板子就行了

3.5.3AC代码
3.5.3.1二进制优化
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
#define sc scanf
inline int read()
{
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            w *= -1;
        ch = getchar();
    }
    while (ch < '0' || ch > '9')
    {
        s = (s << 1) + (s << 3) + (ch ^ 48);
        ch = getchar();
    }

    return s * w;
}
inline void write(int x)
{
    if (x < 0)
        x = -x, putchar('-');
    if (x > 9)
        write(x / 10);
    putchar((x % 10) ^ 48);
}
const int N = 1e5 + 10;
bool f[N];
int c[N * 10], w[N * 10], tot, n, m;

signed main()
{
    //freopen("in.txt", "r", stdin);
    while (~sc("%lld%lld", &m, &n))
    {
        tot = 0, memset(f, 0, sizeof f);
        for (int i = 1, S, W; i <= n; i++)
        {
            sc("%lld%lld", &S, &W);
            // S = read(), W = read();
            for (int j = 1; j <= S; j <<= 1)
                ++tot, c[tot] = w[tot] = j * W, S -= j;
            if (S)
                ++tot, c[tot] = w[tot] = S * W;
        }
        f[0] = 1;
        for (int i = 1; i <= tot; i++)
            for (int j = m; j >= c[i]; j--)
                f[j] = f[j] || f[j - c[i]];
        int ma = m;
        for (; !f[ma]; ma--)
            ;
        write(ma), putchar('\n');
    }
    return 0;
}
3.5.3.2单调队列优化
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
#define sc scanf
inline int read()
{
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            w *= -1;
        ch = getchar();
    }
    while (ch < '0' || ch > '9')
    {
        s = (s << 1) + (s << 3) + (ch ^ 48);
        ch = getchar();
    }

    return s * w;
}
inline void write(int x)
{
    if (x < 0)
        x = -x, putchar('-');
    if (x > 9)
        write(x / 10);
    putchar((x % 10) ^ 48);
}
const int N = 1e5 + 10;
bool f[N], g[N];
int q[N], h, t, n, m;

signed main()
{
    //freopen("in.txt", "r", stdin);
    while (~sc("%lld%lld", &m, &n))
    {
        memset(f, 0, sizeof f), f[0] = 1;
        for (int i = 1, s, w; i <= n; i++)
        {
            sc("%lld%lld", &s, &w), memcpy(g, f, sizeof f);
            for (int j = 0; j < w; j++)
            {
                h = t = 0;
                for (int k = j; k <= m; k += w)
                {
                    if (t - h && q[h] < k - s * w)
                        h++;
                    if (t - h)
                        f[k] = g[k] || g[q[h]];
                    while (t - h && g[k] >= g[q[t - 1]])
                        t--;
                    q[t++] = k;
                }
            }
        }

        int ma = m;
        for (; !f[ma]; ma--)
            ;
        write(ma), putchar('\n');
    }
    return 0;
}

三、总结

在实际刷题过程中,个人感觉二进制优化板子写着最无脑,出错率最低,单调队列有时候还会敲错个变量啥的,而且实测似乎很多题不比单调队列慢,单调队列稍微写错一点就TLE了,当然可能是自己菜(,总体而言,多重背包问题还是比较简单的一类问题,当作变形的01背包就行了。

标签:10,ch,背包,二进制,int,详解,3.1,include,优化
From: https://blog.csdn.net/EQUINOX1/article/details/136679818

相关文章

  • Offer必备算法13_路径dp_六道力扣题详解(由易到难)
    目录①力扣62.不同路径解析代码②力扣63.不同路径II解析代码③力扣LCR166.珠宝的最高价值解析代码④力扣931.下降路径最小和解析代码⑤力扣64.最小路径和解析代码⑥力扣174.地下城游戏解析代码本篇完。①力扣62.不同路径62.不同路径难度中等一个......
  • leetcode: 2861. 最大二进制奇数
    给你一个 二进制 字符串 s ,其中至少包含一个 '1' 。你必须按某种方式 重新排列 字符串中的位,使得到的二进制数字是可以由该组合生成的 最大二进制奇数 。以字符串形式,表示并返回可以由给定组合生成的最大二进制奇数。注意 返回的结果字符串 可以 含前导零。示例......
  • 十分钟掌握分布式数据库开发:OpenMLDB 开发者镜像详解
    OpenMLDB是一款国产的、开源的、面向时序数据的分布式内存数据库系统,它专注于高性能、高可靠性和易扩展性,适用于海量时序数据的处理以及在线特征的实时计算。在大数据和机器学习的浪潮中,OpenMLDB以其强大的数据处理能力和高效的机器学习支持,在开源数据库领域崭露头角。OpenMLDB......
  • 详解Go程序添加远程调用tcpdump功能,exec.Command("sh", "-c", "ps -elf | grep xxx |
    摘自:https://www.jb51.net/article/249001.htm这篇文章主要介绍了go程序添加远程调用tcpdump功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 最近开发的telemetry采集系统上线了。听起来高大上,简单来说就是一个grpc/udp服务端,用......
  • mysql索引详解
    一、介绍索引是通过某种算法,构建出一个数据模型,用于快速找出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的行,表越大,查询数据所花费的时间就越多,如果表中查询的列有一个索引,MySQL能够快速到达一个位置去搜索数据文件,而不必查看所有数......
  • 【图像超分】论文复现:新手入门!Pytorch实现SRCNN,数据预处理、模型训练、测试、评估全流
    文章目录前言1.准备数据集和数据预处理1.1数据集选择1.2数据预处理1.3评估指标PSNR和SSIM1.3.1PSNR1.3.2SSIM2.定义网络结构3.设置参数并训练模型3.1参数设置3.2模型训练4.测试训练好的模型5.用训练好的SRCNN模型超分自己的图像数据6.其他补充6.1特征图......
  • 在Java中如何通过优化代码来节省内存
    Java程序的一个常见问题是高内存使用率,这会导致性能问题甚至崩溃。因此,需要使用内存节省技术来优化Java代码并减少内存使用非常重要。选择正确的数据类型:使用适当大小的数据类型可以避免不必要的内存浪费。例如,如果你知道一个整数的取值范围在-128到127之间,那么使用byte类......
  • 2864.最大二进制奇数
    给你一个 二进制 字符串 s ,其中至少包含一个 '1' 。你必须按某种方式 重新排列 字符串中的位,使得到的二进制数字是可以由该组合生成的 最大二进制奇数 。以字符串形式,表示并返回可以由给定组合生成的最大二进制奇数。注意 返回的结果字符串 可以 含前导零。......
  • go语言接口转换 go语言接口详解
    go语言接口转换go语言接口详解 转载文章标签go语言接口转换Go方法名嵌套文章分类Go语言后端开发阅读数38 一、接口1.1接口类型在Go语言中接口(interface)是一种类型,一种抽象的类型。interface是一组method的集合,是duck-typeprogramming的一种体现。接口做的事情......
  • 《手把手教你》系列技巧篇(三十一)-java+ selenium自动化测试- Actions的相关操作-番外
    1.简介上一篇中,宏哥说的宏哥在最后提到网站的反爬虫机制,那么宏哥在自己本地做一个网页,没有那个反爬虫的机制,谷歌浏览器是不是就可以验证成功了,宏哥就想验证一下自己想法,于是写了这一篇文章,另外也是相对前边做一个简单的总结分享给小伙伴们或者童鞋们。废话不多数,直接进入......