TopCoder SRM 609 Div1 第2题

Problem Statement

 We have balls of K different colors. The colors are numbered 0 through K-1, and the number of balls of color i is X[i]. We want to divide the balls into as few packages as possible. Each package must contain between 1 and K balls, inclusive. Additionally, each package must be either a "normal set" (all balls in the package have the same color), or a "variety set" (no two balls have the same color).
You are given the int K. You are also given ints A, B, C, and D. Use these to generate the array X using the following pseudocode:
X[0] = A
for i = 1 to K-1:
    X[i] = (X[i-1] * B + C) % D + 1

Compute and return the smallest possible number of packages.

Definition

 
Class:PackingBallsDiv1
Method:minPacks
Parameters:int, int, int, int, int
Returns:int
Method signature:int minPacks(int K, int A, int B, int C, int D)
(be sure your method is public)

Limits

 
Time limit (s):2.000
Memory limit (MB):256

Notes

-You can assume that the answer will fit into a signed 32-bit integer.

Constraints

-K will be between 1 and 100,000, inclusive.
-B, C and D will be between 1 and 1,000,000,000, inclusive.
-A will be between 1 and D, inclusive.

Examples

0) 
 
3
4
2
5
6
Returns: 4
There are three colors of balls. Using the pseudocode in the problem statement, we can compute that X[0]=4, X[1]=2, and X[2]=4. As there are 10 balls and we can only put at most 3 into each package, we need at least 4 packages. One possible solution with 4 packages is {0,1,2}, {0,0}, {0,1}, and {2,2,2}. (That is, the first package contains one ball of each color, the second package contains two balls of color 0, and so on.)
1) 
 
1
58
23
39
93
Returns: 58
All the balls have the same color, and each package can only contain one ball. Thus, the number of packages is the same as the number of balls.
2) 
 
23
10988
5573
4384
100007
Returns: 47743
3) 
 

100000
123456789
234567890
345678901
1000000000
Returns: 331988732
Watch out for integer overflow when generating X.


类型:数论  难度:2

题意:有一些球,每个球上有颜色,共k种颜色,给出每种颜色的球的数量x[i],现在要将所有球装到很多包中,每包能装1-k个,分成两种装法:(1)包中球的颜色一样 (2)包中没有任意两个球的颜色一样,求最少需要装几包?

分析:一开始想到的就是把x数组按从小到大排序,然后遍历每种颜色,判断是按(1)装还是用按(2)装,简单的思想就是每个包里装的球越多越好,那么总包数就少了,但是后来发现这种只考虑单个颜色的方法有漏洞,能举出反例证明方法错误,后来参考了别人的代码,思路如下:

1、遍历x数组,若x[i]>k,先装x[i]/k包,每包k个球,保证最优,这样每个颜色都剩于x[i]%k个球,取非零的x[i]%k构成新数组da

2、将da数组排序,从小到大遍历,此时,以当前颜色i为分界,设n为da数组长度

x[k] (k>i) 的球都按(1)分,即每种颜色一包分配(因为x[k]都较大,分成每种颜色一包的话,每包的球更多),共n-i包

x[j] (j<i) 需要判断是按(1)分还是按(2)分,按(1)分配,包数为i(1<=i<=n,),按(2)分,包数为da[i],两个值取最小值即可

记录对于所有的i,n-i+min(i,da[i])的最小值,再加上前面累计的包数,即为所求


代码:

#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<algorithm>
#include<cstdlib>
#include<iostream>
using namespace std;

long long x[100010];

class PackingBallsDiv1
{
public:
    
    int minPacks(int K, int A, int B, int C, int D)
    {
        x[0] = A;
        for(int i=1; i<K; i++)
            x[i] = (x[i-1] * B + C) % (long long)D + 1;
        
        int ans = 0;
        vector<int> da;
        for(int i=0; i<K; i++)
        {
            ans += x[i]/K;
            int tmp = x[i]%K;
            if(tmp)
            {
                da.push_back(tmp);
            }
        }
        if(da.empty())
            return ans;
        sort(da.begin(),da.end());
        int n = da.size();
        int add = min(n,da[n-1]);
        for(int i=0; i<n; i++)
        {
            add = min(add,min(i+1,da[i])+n-i-1);
        }
        return ans+add;
    }
};

int main()
{
    PackingBallsDiv1 t;
    t.minPacks(3,4,2,5,6);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值