poj 1014 硬币分割

来源:互联网 发布:surface rt安装linux 编辑:程序博客网 时间:2024/05/21 17:05
/**              poj 1014 经典多重背包问题 by baiwenlei** 题目大意: 给出一些价值在1~6范围间的弹珠,判断是否能够按照价值等分** 解题思路: 多重背包问题,不过本题中若价值不是偶数,直接返回即可** 最后注意输出的时候要求CASE之间有一个空行,最后一个CASE结束以后不空行。否则presentation error.  我就贡献了一个…… * 最后贡献个数据:* 92 84 76 104 86 131* 32 24 16 14 2 1* 0 0 0 0 0 0* 这个数据是按照我的那个理论设计的。 两个都是CAN。**/#include <iostream>namespace {    using namespace std;    const int VALUE_MAX = 6;    int marble_table[VALUE_MAX+1];    const int MARBLE_NUM_MAX = 20000;    bool reachable[VALUE_MAX*MARBLE_NUM_MAX/2 + 1]; // 最多20000个弹珠,等分值除以2    inline void zero_one(int V, int v)    {        for (int i=V; i>=v; --i)        {            if (!reachable[i])            {                reachable[i] = reachable[i-v];            }        }    }    inline void complete(int V, int v)    {        for (int i=v; i<=V; ++i)        {            if (!reachable[i])            {                reachable[i] = reachable[i-v];            }        }    }        inline void multiple(int V, int v, int n)    {        if (n*v >= V)        {            complete(V, v);            return;        }                int r = n;        for (int k=1; k<r; k*=2)        {             zero_one(V, k*v);              r -= k;        }        zero_one(V, r*v);            }        bool could_split_fairly(int value)    {        if (value & 1)        {            return false;        }        int half_value = (value >> 1);        for (int i=0; i<=half_value; i++)        {            reachable[i] = false;        }        reachable[0] = true;        for (int i=1; i<=VALUE_MAX; i++ )        {            int count = marble_table[i];                        if (count==0) continue;            multiple(half_value, i, count);        }        return reachable[half_value];    }}int main(){    int n = 0;    while (true)    {        ++n;                int sum = 0;        for (int i=1; i<=VALUE_MAX; i++)        {            cin >> marble_table[i];            sum += (marble_table[i] * i);        }        if (sum == 0) break; // 退出条件        cout << "Collection #" << n << ":" << endl;        cout << (could_split_fairly(sum) ? "Can be divided." : "Can't be divided.") << endl << endl;    }    return 0;}


原创粉丝点击