可恶的C题
问题 C: 母鸡下蛋
时间限制: 1 Sec
内存限制: 128 MB
提交: 196
解决: 44
[ 提交][ 状态][ 讨论版]
题目描述
鸡国中的母鸡最擅长下蛋了,MGMG 是鸡国中一只以下蛋产量高而闻名全鸡国的母鸡。
鸡国专供下蛋的 n 个鸡窝呈一字排列在鸡国的“下蛋中心”,从左到右依次编号为 1 到n。每个鸡窝都有一个最大可下蛋的量,其中第 i 个鸡窝的最大可下蛋量为 ci 。有时候由于MGMG 产量实在太大而无法在一个鸡窝中下完所有的蛋,不得不转移到隔壁的鸡窝继续下蛋,如果隔壁的鸡窝还是不能让它下完所有的蛋,则 MGMG 继续转移,直到下完所有的蛋,或者向“下蛋中心”管理员投诉“鸡窝数量实在太少了,我一只鸡的下蛋量都装不下!”。
为了节省转移时所耗费的体力,请你编程帮助 MGMG 找若干个连续的鸡窝(个数尽量少),让它能下完所有的蛋。
输入
输入共 2 行。
第 1 行输入两个整数 n 和 t,表示“下蛋中心”有 n 个可供下蛋的鸡窝,MGMG 一次总共要下 t 个鸡蛋。
第 2 行 n 个正整数 ci (1≤i≤n),依次表示第 i 个鸡窝最大可下蛋量为 ci 个。
输出
输出 1 行一个整数或一个单词。当输出整数时表示让 MGMG 下完所有的蛋至少需要几个连续的鸡窝。当 MGMG 用完所有的鸡窝都无法下完所有的蛋时,MGMG 表示非常愤怒,输出单词“Angry”(不包含双引号,注意大小写)。
样例输入
5 4
1 2 1 2 3
样例输出
2
C题模拟肯定会超时,题意类似于求最大间隙问题。不妨用一个数组来储存前i项和,用一个数x来记录左下标,枚举前i项和,当i大于x的时候,求出差值,用差值跟母鸡的蛋比较,再记录最小i-x的差值,最后输出差值。若一开始蛋大于所有窝的和输出angry. 由于差值不断增大,所以最后求出的i-x的差值肯定是最小。线性时间。
代码实现:
#include
#include
#include
using namespace std;
int main()
{
int dp[100005],i,j,k,n,t,x,len;
while(cin>>n>>t)
{
len=0x3f3f3f3f;
memset(dp,0,sizeof(dp)); //清空数组
for(i=1;i<=n;i++)
{
cin>>x;
dp[i]=dp[i-1]+x; //前i项和
}
if(t>dp[n])
{
cout<<"Angry"<x&&dp[i]-dp[x]>=t)
{
len=min(len,i-x);
x++; //下标后移
}
}
cout<
可恶的H题
问题 H: wtaxi
时间限制: 1 Sec
内存限制: 128 MB
提交: 58
解决: 29
[ 提交][ 状态][ 讨论版]
题目描述
话说小 x 有一次去参加比赛,虽然学校离比赛地点不太远,但小 x 还是想坐出租车去。大学城的出租车总是比较另类,有“拼车”一说,也就是说,你一个人坐车去,还是一堆人一起,总共需要支付的钱是一样的(每辆出租上除司机外最多坐下 4 个人)。刚好那天同校的一群 Oier 在校门口扎堆了,大家果断决定拼车去赛场。
问题来了,一辆又一辆的出租车经过,但里面要么坐满了乘客,要么只剩下一两个座位,众 Oier 都觉得坐上去太亏了,小 x 也是这么想的。
假设 N 位 Oier 准备拼车,此时为 0 时刻,从校门到目的地需要支付给出租车师傅 D 元(按车次算,不管里面坐了多少 Oier),假如 S 分钟后恰能赶上比赛,那么 S 分钟后经过校门口的出租车自然可以忽略不计了。现在给出在这 S 分钟当中经过校门的所有的 K 辆出租车先后到达校门口的时间 Ti 及里面剩余的座位 Zi(1 <= Zi <= 4),Oier 可以选择上车几个人(不能超过),当然,也可以选择上 0 个人,那就是不坐这辆车。
俗话说,时间就是金钱,这里小 x 把每个 Oier 在校门等待出租车的分钟数等同于花了相同多的钱(例如小 x 等待了 20 分钟,那相当于他额外花了 20 元钱)。
在保证所有 Oier 都能在比赛开始前到达比赛地点的情况下,聪明的你能计算出他们最少需要花多少元钱么?
输入
每组数据以四个整数 N , K , D , S 开始,具体含义参见题目描述。
接着 K 行,表示第 i 辆出租车在第 Ti 分钟到达校门,其空余的座位数为 Zi(时间按照先后顺序)。
N <= 100,K <= 100,D <= 100,S <= 100,1 <= Zi <= 4,1<= T(i) <= T(i+1) <= S
输出
对于每组测试数据,输出占一行,如果他们所有人能在比赛前到达比赛地点,
则输出一个整数,代表他们最少需要花的钱(单位:元),否则请输出“impossible”。
样例输入
2 2 10 5
1 1
2 2
样例输出
14
典型的dp,可以用二维数组,dp[i][j]表示i辆车装j个人时花的时间,也可以用一维数组,dp【i】表示第i个人的最小钱数。一维dp类似于背包问题。
贴一下二维dp的代码,附赠一维dp的题解地址:点击打开链接
代码实现:
#include
#include
#include
#include
using namespace std;
int main()
{
int n,k,d,s,dp[105][105],i,j,o,a,b; //dp[i][j]表示i辆车装j个人时花的时间
while(cin>>n>>k>>d>>s)
{
memset(dp,0x3f3f3f3f,sizeof(dp));
dp[0][0]=0;
for(i=1;i<=k;i++)
{
for(j=0;j<=n;j++)
dp[i][j]=dp[i-1][j]; //初始化数组
cin>>a>>b;
for(j=0;j<=n;j++) //枚举人
for(o=0;o<=b;o++) //枚举坐多少人
if(j>=o)
dp[i][j]=min(dp[i-1][j-o]+o*a+d,dp[i][j]);
}
if(dp[k][n]!=0x3f3f3f3f)
cout<
可恶的G题
问题 G: 【动态规划】cirs
时间限制: 1 Sec
内存限制: 128 MB
提交: 124
解决: 48
[ 提交][ 状态][ 讨论版]
题目描述
Czyzoiers 都想知道小 x 为什么对鸡蛋饼情有独钟。经过一番逼问,小 x 道出了实情:因为他喜欢圆。最近小 x 又发现了一个关于圆的有趣的问题:在圆上有2N 个不同的点,小 x 想用 N 条线段把这些点连接起来(每个点只能连一条线段),使所有的线段都不想交,他想知道这样的连接方案有多少种?
输入
有且仅有一个正整数 N(N≤3000)。
输出
要求的方案数(结果 mod 100000007)。
样例输入
2
样例输出
2
提示
1 号点与 2 号点连接:2 种。
1 号点与 4 号点连接:1 种。
1 号点与 6 号点连接:2 种。
传说中的dp,卡特兰数直接套公式就可以得到。由于才学疏浅,硬生生把公式推了出来。可以看示例,他将圆分成了两份,其中两份都是前面得到的。
代码实现:
#include
#include
using namespace std;
int main()
{
long long n,i,a[3005],j;
a[0]=1;a[1]=1;a[2]=2;
for(i=3;i<3005;i++)
for(j=1;j<=i;j++)
a[i]=(a[i]+a[i-j]*a[j-1])%100000007;
while(cin>>n)
{
cout<