Cod sursa(job #952262)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 22 mai 2013 23:11:30
Problema Ghiozdan Scor 36
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.81 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <array>
#include <algorithm>
#include <iterator>

#define MAX_WEIGHT 201
#define MAX_ITEMS 20002
#define MAX_CAPACITY 75001

using namespace std;

struct ItemsPacked
{
    ItemsPacked()
    {
        LastItem[0] = LastItem[1] = 0;
        NumItems[0] = NumItems[1] = MAX_ITEMS;
        Items.fill(0);
    }
    
    void PushMinimum(unsigned char item, short itemCount)
    {
        if (itemCount <= NumItems[0])
        {
            Items[LastItem[0]]--;
            Items[item]++;
            
            NumItems[1] = NumItems[0];
            LastItem[1] = LastItem[0];

            NumItems[0] = itemCount;
            LastItem[0] = item;
        }
        else if (itemCount < NumItems[1])
        {
            NumItems[1] = itemCount;
            LastItem[1] = item;
        }
    }

    unsigned char LastItem[2];
    short NumItems[2];
    array<unsigned char, MAX_WEIGHT> Items;
};

array<short, MAX_WEIGHT> maxItemsOfType;
array<ItemsPacked, MAX_CAPACITY> itemsPacked;

int main()
{
    int n, G;
    fstream fin("ghiozdan.in", fstream::in);
    fstream fout("ghiozdan.out", fstream::out);

    fin >> n >> G;
    //cout << n << " " << G << endl;

    for (int i=0; i<n; ++i)
    {
        int itemIndex;
        fin >> itemIndex;

        maxItemsOfType[itemIndex]++;
    }

    for (int item=200; item>0; --item)
    {
        if (maxItemsOfType[item] == 0) continue;

        itemsPacked[item].LastItem[0] = item;
        itemsPacked[item].NumItems[0] = 1;
        itemsPacked[item].Items[item] = 1;

        for (int i=item+1; i<=G; ++i)
        {
            //cout << "Trying " << i << " " << itemsPacked[i - item].NumItems << " " << itemsPacked[i].NumItems << endl;
            if (itemsPacked[i - item].NumItems[0] == MAX_ITEMS) continue;
            
            if (itemsPacked[i - item].Items[item] == maxItemsOfType[item])
            {
                itemsPacked[i].PushMinimum(item, itemsPacked[i - item].NumItems[1] + 1);
            }
            else
            {
                itemsPacked[i].PushMinimum(item, itemsPacked[i - item].NumItems[0] + 1);
            }
        }

        //cout << "(" << item << " " << maxItemsOfType[item] << ") ";
    }
    //cout << endl;

    for (int i=MAX_CAPACITY-1; i>0; --i)
    {
        if (itemsPacked[i].NumItems[0] < MAX_ITEMS)
        {
            fout << i << " " << itemsPacked[i].NumItems[0] << "\n";
            
            /*int lastItem = itemsPacked[i].LastItem[0];
            while (lastItem != 0)
            {
                cout << lastItem << "\n";
                
                lastItem = itemsPacked[i - lastItem].LastItem[0];
            }*/

            break;
        }
    }

    return 0;
}