【坑爹】2016.11.8 清北学堂钟长者的P73

坑爹考试,习惯性爆零

第一个题一眼高精不想打
第二个题一眼接水问题不到20分钟打完WA
第三个题没看出来以为是DP一直搞(正解:贪心)


T2:死亡

【问题描述】
现在有M个位置可以打sif,有N+1个人在排队等着打sif。现在告诉你前N个人每个人需要多长的时间打sif,问你第N+1个人什么时候才能打sif。(前N个人必须按照顺序来)
【输入格式】
第一行两个整数N,M如上所述。
接下来N行每行一个整数代表每个人所需要用的时间。
【输出格式】
一行一个整数表示答案。
【样例输入】
3 2
1
1
1
【样例输出】
1
【样例解释】
山里有座庙。
【数据规模与约定】
对于100%的数据,每个人所需用的时间不超过〖10〗^5。
测试点 N M 测试点 N M
1 10 10 1 5000 500
2 20 10 2 100000 5000
3 50 10 3 100000 10000
4 1000 500 4 100000 20000
5 2000 500 5 100000 50000

贪心+模拟+优先队列
当时心血来潮打了个不到60行的代码交上去了

代码如下:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>

const int maxn = 100100;

using namespace std;
typedef long long LL;

LL n,m;
LL ans = 0x3ffffff;
LL w[maxn];

priority_queue<LL,vector<LL >,greater<LL > >q;

inline LL read()
{
    LL f = 1;
    LL data = 0;
    char ch;
    while(ch < '0'||ch >'9')
    {
        ch = getchar();
        if(ch == '-') f = -1;
    }
    do{
        data = data*10+ch-'0';
        ch = getchar();
    }while(ch <= '9'&&ch >= '0');
return f*data;
}

inline void search()
{
    for(int i = 1; i <= min(n,m);i++)
    {
        int x = q.top();
        q.pop();
        x += w[i];
        q.push(x);
    }
    while(!q.empty())
    {
        ans = min(ans,q.top());
        q.pop();
    }
}

int main()
{
    //freopen("death.in","r",stdin);
    //freopen("death.out","w",stdout);
    scanf("%I64d %I64d",&n,&m);
    for(LL i = 1;i <= n;i++)
    {
        w[i] = read();
    }
    sort(w+1,w+n+1);
    if(n <= m)
    {
        printf("%I64d\n",w[1]);
        return 0;
    }
    for(int i = 1;i <= min(n,m);i++) q.push(0); 
    search();
    printf("%I64d\n",ans);

return 0;
}

T3:凝视

【问题描述】
背包是个好东西,希望我也有。
给你一个二维的背包,它的体积是N×M。现在你有一些大小为1×2和1×3的物品,每个物品有自己的价值。你希望往背包里面装一些物品,使得它们的价值和最大,问最大的价值和是多少。
【输入格式】
第一行一个整数T代表该测试点的数据组数。
对于每组数据,第一行有四个整数N,M,n_1,n_2,其中n_1,n_2分别代表大小为1×2和大小为1×3的物品个数。
接下来一行有n_1个数代表每个1×2物品的价值。
接下来一行有n_2个数代表每个1×3物品的价值。
【输出格式】
对于每组询问,输出能够达到的价值最大值。
【样例输入】
1
2 3 2 2
1 2
1 2
【样例输出】
4
【样例解释】
庙里有座山。
【数据规模与约定】
对于20%的数据,N,M≤10,n_1,n_2≤100。
对于70%的数据,N,M≤100,n_1,n_2≤2000。
对于100%的数据,1≤T≤10,1≤N,M≤500,0≤n_1,n_2≤10000。


题面上来说”背包是个好东西”,其实是带有迷惑性的(滑稽),正解贪心(Orz 红太阳柳畅)

思路:我们不需要管怎么放,因为只要有空间够放,就一定可以放(见带限制的俄罗斯方块)
但是有的特殊情况需要特判一下,即2X2的空间
首先显然这种空间放不进去1X3的物品
其次,当我们将一个空间填满1X3的物品时总会发现,剩余的格子数一定远小于1X3所占有的空间且该空间最大为2X2(总空间一定是一个矩形)

所以代码如下(基本抄的神犇代码,加了点小优化):

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>

const int maxn = 10010;

using namespace std;

int t;
int N,M,n1,n2;
bool used[maxn];

struct node{
    int num,w;
}s1[maxn],s2[maxn];

inline bool cmp(node a,node b)
{
    return a.w > b.w;
}

inline int read()
{
    int f = 1;
    int data = 0;
    char ch;
    while(ch < '0'||ch > '9')
    {
        ch = getchar();
        if(ch == '-')
            f = -1;
    }
    do{
        data = data*10 + ch-'0';
        ch = getchar();
    }while(ch <= '0'&&ch >= '9');

return data*f;
}

int main()
{
    freopen("eyesight.in","r",stdin);
    freopen("eyesight.out","w",stdout);
    scanf("%d",&t);
    for(int i = 1;i <= t;i++)
    {
        int sum;
        N = read(),M = read(),n1 = read(),n2 = read();
        for(int i = 1;i <= n1;i++) 
        {
            s1[i].w = read();
            sum += s1[i].w;
            s1[i].num = i;
        }
        for(int i = 1;i <= n2;i++) 
        {
            s2[i].w = read();
            sum += s2[i].w;
            s2[i].num = i;
        }
        if(N == 0||M == 0) {puts("0\n"); return 0;}
        if(N == 1&&M == 1) {puts("0\n"); return 0;}
        sort(s2+1,s2+n2+1,cmp);
        sort(s1+1,s1+n1+1,cmp);
        used[1] = 1;
        printf("%d\n",sum);
    }
fclose(stdin);
fclose(stdout);
return 0;
}

友情提示:下场考试庙前有棵树,树上有只鸟

THE END

By Peacefuldoge

http://blog.csdn.net/loi_peacefuldog

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值