[USACO]nuggets

Beef McNuggets
Hubert ChenFarmer Brown's cows are up in arms, having heard that McDonalds is considering the introduction of a new product: Beef McNuggets. The cows are trying to find any possible way to put such a product in a negative light.

One strategy the cows are pursuing is that of `inferior packaging'. ``Look,'' say the cows, ``if you have Beef McNuggets in boxes of 3, 6, and 10, you can not satisfy a customer who wants 1, 2, 4, 5, 7, 8, 11, 14, or 17 McNuggets. Bad packaging: bad product.''

Help the cows. Given N (the number of packaging options, 1 <= N <= 10), and a set of N positive integers (1 <= i <= 256) that represent the number of nuggets in the various packages, output the largest number of nuggets that can not be purchased by buying nuggets in the given sizes. Print 0 if all possible purchases can be made or if there is no bound to the largest number.

The largest impossible number (if it exists) will be no larger than 2,000,000,000.

PROGRAM NAME: nuggets

INPUT FORMAT

Line 1: N, the number of packaging options
Line 2..N+1: The number of nuggets in one kind of box

SAMPLE INPUT (file nuggets.in)

3
3
6
10

OUTPUT FORMAT

The output file should contain a single line containing a single integer that represents the largest number of nuggets that can not be represented or 0 if all possible purchases can be made or if there is no bound to the largest number.

SAMPLE OUTPUT (file nuggets.out)

17

-------------------------------分割线---------------------------

这道题看上去就是DP,很简单。关键的问题是数组申请多大。我们把N个数排序后,最小的数设为nMin,则我们的数组只需要有nMin+1 这个大,就可以循环使用了。因为 0 --nMin, 1 -- (1 + nMin)%(nMin+1), 2-- (2 + nMin)%(nMin+1).

由于比较简单,就不写伪代码了。唯一需要注意的是,何时输出为0,即没有这个最大值---------N个数的最大公约数不为1时(证明:假设公约数为g,则k*g+1 总是满足无法拼出的条件)。另外,我们可以通过归纳法证明,N个数,至多达到他们的最小公倍数的时候,必然可以有连续nMin个可以拼出的数。

补充:看了标程才明白数组大小只要256就可以了。 因为 0  -- 256 % 256 = 0  ,  1 -- 257 % 256 = 1 , 这样状态最多由下标自身去回退,仍然可以保证数组的循环使用。

--------------------------代码分割线--------------------------

/*
ID: zhangyc1
LANG: C++
TASK: nuggets
*/
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
using namespace std;

ofstream fileout("nuggets.out");
int N, arrBoxes[10];

struct Record
{
    bool bValid;
    int nLen;
    Record(){bValid = false; nLen = 0;}
};

const int RecordNum = 257;
Record arrRecord[RecordNum];
int nGreast = 0;

int compare(const void* argv1, const void* argv2)
{
    return *((int*)argv1) - *((int*)argv2);
}

inline void swap(int x, int y){int temp = x; x = y; y = temp;}

void prepairData()
{
    ifstream filein("nuggets.in");
    filein >> N;
    for (int i = 0; i < N; i++)
    {
        filein >> arrBoxes[i];
    }
    qsort(arrBoxes, N, sizeof(int), compare);
    arrRecord[0].bValid = true;
    arrRecord[0].nLen = 0;
    filein.close();
}

int GCD(int x, int y)
{
    if (x < y)
        swap(x,y);
    int temp;
    while(x)
    {
        temp = x;
        x = y % x;
        y = temp;
    }
    return y;
}

void process()
{
    int nGcd = arrBoxes[0];
    for (int i = 0; i < N; i++)
    {
        nGcd = GCD(nGcd, arrBoxes[i]);
    }
    if (nGcd != 1)
    {
        fileout << 0 << endl;
        return;
    }

    int nCurPos = 1;
    while (1)
    {
        bool bVa = false;
        for (int i = 0; i < N; i++)
        {
            if (arrRecord[(RecordNum + nCurPos - arrBoxes[i]) % RecordNum].bValid)
            {
                bVa = true;
                break;
            }
        }
        arrRecord[nCurPos % RecordNum].bValid = bVa;
        if (bVa)
        {
            arrRecord[nCurPos % RecordNum].nLen = arrRecord[(nCurPos - 1 + RecordNum) % RecordNum].nLen + 1;
            // 已可以连续
            if (arrRecord[nCurPos % RecordNum].nLen == arrBoxes[0])
            {
                break;
            }
        }
        else
        {
            nGreast = nCurPos;
            arrRecord[nCurPos % RecordNum].nLen = 0;
        }
        nCurPos++;
    }

    fileout << nGreast << endl;
}

int main(){
    prepairData();
    process();
    fileout.close();
    return 0;
}

----------------------------------------------------

Here are the test data inputs:

------- test 1 ----
3
3
6
10
------- test 2 ----
2
2
3
------- test 3 ----
1
1
------- test 4 ----
4
252
250
254
256
------- test 5 ----
2
255
254
------- test 6 ----
5
251
252
250
254
256
------- test 7 ----
10
238
240
242
244
246
248
250
252
254
255
posted @ 2013-03-01 12:29  J.Z's World  阅读(347)  评论(0编辑  收藏  举报