坑爹考试,习惯性爆零
第一个题一眼高精不想打
第二个题一眼接水问题不到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