您的位置:首页 > 其它

10-24机房测试

2017-10-25 10:44 288 查看
出现的问题:

T1我贪错心了。。。。。。

T2是从1-k任何一个房间走都可以走到1,k+1-n任何一个走不能走到1.

我理解反了,理解成了存在性问题,写出来的爆暴力样例都过不了。。。

T3人家巨人只能往前跳,我认为可以往后跳。于是我认为这题太麻烦了,做个屁啊。

然后今天就GG了

很绝望啊。

T1 小G搭积木

题目描述

小 G 喜欢搭积木。小 G 一共有 n 块积木,并且积木只能竖着一块一块的摞,可

以摞多列。小 G 的积木都是智能积木,第 i 块积木有一个情绪值 X i 。当摞在该积

木上面积木总数超过 X i 时,i 号积木就会不高兴。小 G 情商这么高,肯定不希望

有积木不高兴。但是他又希望每块积木都被用上,并且摞的积木列的总数最少。你

能帮帮萌萌的小 G 吗?

输入格式

输入文件第一行一个数字 n,含义如题目所述。

第 2 行一共 n 个数,第 i 个数为 X i ,含义如题目所述。

输出格式

输出一个数字,表示最小的积木列数目

样例输入 1

3

0 0 10

样例输出 1

2

样例输入 2

4

0 0 0 0

样例输出 2

4

数据范围

30% 数据,1 ≤ n ≤ 10

60% 数据,1 ≤ n ≤ 100

80% 数据,1 ≤ n ≤ 1000

100% 数据,1 ≤ n ≤ 5000

对于所有数据点,都有 X i ≤ n

正解贪心:

把往上添方块变为往下垫方块。

把方块从小到大添上去。

一定要找一摞方块数跟当前添的方块最接近的,这样才发挥了最大作用。

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxm=9999;
int q[maxm];
int h[maxm],tot;
bool comp(int a,int b)
{
return a>b;
}
int main()
{
freopen("box.in ","r",stdin);
freopen("box.out","w",stdout);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&q[i]);
sort(q+1,q+n+1);
int tot=1;
h[1]=1;
for(int i=2;i<=n;i++)
{
int id=0;
for(int j=1;j<=tot;j++)
if(h[j]<=q[i])
{
if(id==0) id=j;
else
if(h[id]<h[j]) id=j;
}
if(id==0) h[++tot]=1;
else h[id]++;
}
printf("%d",tot);
}


T2 小 G 的城堡

题目描述

小 G 家有一座城堡。城堡里面有 n 个房间,每个房间上都写着一个数字 p i 。小

G 拉着几个小伙伴在城堡里面玩耍,他们约定,如果某个人当前站在 i 房间里面,下

一步这个人就会去 p i 房间,再下一步这个人去 p p i 。

为了增加趣味性,小 G 想重新书写每个房间的 p i ,以满足:

• 如果从编号 1 到 k 中的某个房间开始,按照规则走,必须能够走到 1 号房间。

特别地,如果从 1 号房间开始走,也要能够走回 1 号房间(至少走一步,如果

p 1 = 1,从 1 走到 1 也算合法)。

• 如果从编号大于 k 的某个房间开始,按照规则走,一定不能走到 1 号房间。

小 G 想知道,有多少种书写 p i 的方案,可以满足要求。

输入格式

输入文件一行两个数字 n,k,含义如题。

输出格式

输出文件一个数字,表示合法的方案数。答案对 10 9 + 7 取模。

样例输入 1

5 2

样例输出 1

54

样例输入 2

7 4

样例输出 2

1728

数据范围

对于 40% 的数据,1 ≤ n ≤ 8

对于 70% 的数据,1 ≤ n ≤ 10 5

对于 100% 的数据,1 ≤ n ≤ 10 18 ,1 ≤ k ≤ min(8,n)。

对于1-k联通的方案数,我们可以用暴力求出来。

k最大为8,打表即可。

后面的只能和后面的连,方案数即为(n-k)^(n-k)。

后来发现前面的方案数为(k-1)^k

乘法原来搞一搞,快速幂即可。

#include <cstdio>
#include <iostream>
#define ll long long
using namespace std;
const int mod=1e9+7;
ll n,k,ans;
ll fast_pow(ll x,ll y)
{
ll ans=1;
while(y)
{
if(y%2) ans=(ans*x)%mod;
y/=2ll;
x=(x*x)%mod;
}
return ans%mod;
}
int main()
{
scanf("%lld%lld",&n,&k);
printf("%lld",fast_pow(k,k-1)*fast_pow(n-k,n-k)%mod);
}


T3 跳跃

题目描述

美丽国有 n 座小岛。这些小岛排成了一条直线,依次编号为 0,1,2,3… 有的小岛

上有金块,有的小岛上没有。美丽国有一个巨人 Bob,有一天他决定从第 0 个岛开

始,一直往后跳,看看自己能收集多少金块。

当然,Bob 不是没有目的性的乱跳;相反,Bob 的跳跃要满足以下规则:

• 首先 Bob 从 0 跳到 d 岛屿

• 假如 Bob 上一次跳了 l 步,则 Bob 下一次可以选择跳 l、l − 1、l + 1 步。注

意:所跳的步数不能小于 1,即如果上一次跳跃的步数为 1,下一次跳跃的步

数只能是 1 或者 2。

在这样的规则下,Bob 想知道,他最多能拿到多少金块?

输入格式

输入第一行两个整数 n,d,分别表示有金块的岛屿的个数,和 Bob 第一步要

跳的步数。

接下来 n 行,每行一个整数 id,表示编号为 id 的岛屿上有金块。

输出格式

输出仅一行,表示 Bob 最多能收集多少金块。

样例输入 1

4 10

10

21

27

27

样例输出 1

3

样例输入 2

8 8

9

19

28

36

45

55

66

78

样例输出 2

6

数据范围

对于 30% 的数据,1 ≤ n,d,id ≤ 100

对于 70% 的数据,1 ≤ n,d,id ≤ 1000

对于 100% 的数据,1 ≤ n,d,id ≤ 30000

DP[i][j]为i位置下次跳j步能捡到的最多的金子数目。

转移

DP[i][j]=max(DP[i+j][j-1],DP[i+j][j+1],dp[i+j][j])+a[i]。

j多大?30000?

空间不够。

考虑一下最多最少跳几步。

最坏的情况,从1开始走。

每次+1

那么最多跳的步数即为 初始+n(n+1)/2

最小的同理。

#include <cstdio>
#include <iostream>
using namespace std;
int flag[30021];
int dp[30021][3001];
int main()
{
int n,d;
int max_d=0;
scanf("%d%d",&n,&d);
for(int i=1,x;i<=n;i++)
scanf("%d",&x),flag[x]++,max_d=max(max_d,x);
for(int i=max_d;i>=d;i--)
for(int j=0;j<=700;j++)
{
int x=j-350;
if(d+x<0) continue;
dp[i][j]=flag[i];
if(i+d+x<=max_d)
dp[i][j]+=max(max(dp[i+d+x][j-1],dp[i+d+x][j]),dp[i+d+x][j+1]);
}
printf("%d",max(dp[d][350],max(dp[d][349],dp[d][351])));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: