ACM ICPC 2013-2014 F. Illegal spices(贪心法)

Decription
n个袋子,现在扔掉n-k个最后留下k个,怎么扔?首先第一个必须要扔;然后对于后面的第i个,统计前i-1个中比第i个重量轻的个数cnt,若cnt所占的比例即cnt/(i-1)>=p%则这个袋子不扔。现在告诉起始有n个袋子最后剩下k个,让你构造n个袋子的重量使得总重量最小
Input
三个整数n,k,p
Output
输出n的袋子的最小总质量并输出每个袋子的重量,如有多组可行解输出其中一组即可
Sample Input
3 1 50
Sample Output
4
1 2 1
Solution
贪心,首先不妨将前n-k个袋子扔掉,那么此时前n-k个袋子的质量和最小即为n-k,此时每个袋子质量都为1,对其中任一袋子都有cnt/(i-1)=0

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
#define maxn 111111
ll n,k,p,a[maxn];
int main()
{
    while(~scanf("%I64d%I64d%I64d",&n,&k,&p))
    {
        ll sum=n-k;//总质量初始化为n-k 
        for(ll i=1;i<=n-k;i++)//前n-k个袋子质量均为1 
            a[i]=1;
        ll now=2;//当前满足条件的袋子质量最小值 
        ll cnt=n-k;//小于当前袋子质量最小值的袋子数 
        for(ll i=n-k+1;i<=n;i++)
        {
            if(cnt*100ll>=(i-1)*p)//当前袋子质量最小值仍然满足条件
                a[i]=now;
            else//当前袋子质量最小值不满足条件则将当前袋子质量最小值加一 
            {
                a[i]=++now;
                cnt=i-1;//更新小于当前袋子质量最小值的袋子数 
            }
            sum+=a[i];//累加每个袋子的质量 
        }
        printf("%I64d\n",sum);
        for(ll i=1;i<=n;i++)
            printf("%I64d%c",a[i],i==n?'\n':' ');
    }
    return 0;
}

你可能感兴趣的:(ACM ICPC 2013-2014 F. Illegal spices(贪心法))