用bitset位操作代替逐个询问

已存在,只需 存在,就有 存在

而题意只需要价值存在即可

利用鬼谷子的钱包的分治思想优化解法

#include <cstdio>
#include <bitset>
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define LL long long
#define IN freopen("in.txt", "r", stdin)
#define OUT freopen("out.txt", "w", stdout)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define sqr(x) (x) * (x)
#define pr1(x) printf("Case %d: ", x)
#define pn1(x) printf("Case %d:\n", x)
#define pr2(x) printf("Case #%d: ", x)
#define pn2(x) printf("Case #%d:\n", x)
#define lowbit(x) (x & (-x))

typedef unsigned long long ull;

struct FastIO
{
    static const int S = 5 << 20; //MB
    int wpos;
    char wbuf[S];
    FastIO() : wpos(0) {}
    inline int xchar()
    {
        static char buf[S];
        static int len = 0, pos = 0;
        if (pos == len)
            pos = 0, len = fread(buf, 1, S, stdin);
        if (pos == len)
            return -1;
        return buf[pos++];
    }
    inline int xuint()
    {
        int c = xchar(), x = 0;
        while (~c && c <= 32)
            c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar())
            x = x * 10 + c - '0';
        return x;
    }
    inline LL xull()
    {
        int c = xchar();
        LL x = 0;
        while (~c && c <= 32)
            c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar())
            x = x * 10 + c - '0';
        return x;
    }
    inline int xint()
    {
        int s = 1, c = xchar(), x = 0;
        while (c <= 32)
            c = xchar();
        if (c == '-')
            s = -1, c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar())
            x = x * 10 + c - '0';
        return x * s;
    }
    inline void xstring(char *s)
    {
        int c = xchar();
        while (c <= 32)
            c = xchar();
        for (; c > 32; c = xchar())
            *s++ = c;
        *s = 0;
    }
    inline void wchar(int x)
    {
        if (wpos == S)
            fwrite(wbuf, 1, S, stdout), wpos = 0;
        wbuf[wpos++] = x;
    }
    inline void wll(LL x)
    {
        if (x < 0)
            wchar('-'), x = -x;

        char s[30];
        int n = 0;
        while (x || !n)
            s[n++] = '0' + x % 10, x /= 10;
        while (n--)
            wchar(s[n]);
    }
    inline void wstring(const char *s)
    {
        while (*s)
            wchar(*s++);
    }
    ~FastIO()
    {
        if (wpos)
            fwrite(wbuf, 1, wpos, stdout), wpos = 0;
    }
} io;

LL s, sum, a[7], cnt;
bitset<20000> dp;

int main()
{
    //IN;
    // OUT;
    while (++cnt)
    {
        s = 0;
        dp.reset();
        dp.set(0);
        f(i, 1, 6)
            s += (a[i] = io.xint()) * i;
        //io.wll(s);
        if (s == 0)
            break;
        io.wstring("Collection #");
        io.wll(cnt);
        io.wchar(':');
        io.wchar('\n');
        if (s & 1)
            io.wstring("Can't be divided.\n\n");
        else
        {
            s >>= 1;
            f(i, 1, 6)
            {
                for (int j = a[i]; j > 0; j >>= 1)
                {
                    int k = ((j + 1) >> 1) * i;
                    dp |= (dp << k);
                    if (dp[s])
                    {
                        break;
                    }
                }
                if (dp[s])
                    break;
            }
            if (dp[s])
                io.wstring("Can be divided.\n\n");
            else
                io.wstring("Can't be divided.\n\n");
        }
    }
}
此文章已被阅读次数:正在加载...更新于