C/C++编程(1~8级)全部真题・点这里
Python编程(1~6级)全部真题・点这里
Santo刚刚与房东打赌赢得了一间在New Clondike 的大客厅。今天,他来到这个大客厅欣赏他的奖品。房东摆出了一行瓶子在酒吧上。瓶子里都装有不同体积的酒。令Santo高兴的是,瓶子中的酒都有不同的味道。房东说道:“你可以喝尽可能多的酒,但是一旦打开酒盖你就必须把它喝完,喝完一瓶后把它放回原处。还有一件最重要的事,你必须从左至右依次喝,并且不能连续超过三瓶,不然会给你带来坏运气。”现在可怜的Santo站在酒吧前努力的想着,他到底应该喝哪几瓶才能使喝的酒最多呢?请帮助他找出他应该喝的酒瓶号,因为思考让他感到不安。
时间限制:2000
内存限制:131072
输入
第一行一个整数N,有N个酒瓶。N<=700接下有N行,第I+1行的数字代表酒瓶I中酒的体积。
输出
一个数字,喝的酒的最大总体积。遵守以上规则,使得三个连续瓶子中至少一个瓶子是满的。
样例输入
6
6
10
13
9
8
1
样例输出
33
这个问题可以使用动态规划来解决。我们可以定义一个数组dp
,其中dp[i]
表示从第1瓶到第i瓶中可以喝的最大总体积。然后,我们可以使用以下递推关系来计算dp[i]
的值:
如果只有一瓶酒(i = 1
),则dp[i]
等于该酒瓶的体积。
如果有两瓶酒(i = 2
),则dp[i]
等于前两瓶酒瓶体积的最大值。
如果有三瓶或更多的酒(i >= 3
),则有两种情况:
情况一:喝第i瓶酒,那么前两瓶酒中至少有一瓶是满的。此时,dp[i]
等于第i瓶酒的体积加上dp[i-2]
。
情况二:不喝第i瓶酒,那么前两瓶酒中至少有两瓶是满的。此时,dp[i]
等于dp[i-1]
。
最后,我们返回dp[N]
作为喝的酒的最大总体积。以下是使用C语言编写的解决方案:
#include
int max(int a, int b) {
return (a > b) ? a : b;
}
int maxDrinkingVolume(int volumes[], int N) {
int dp[702]; // dp数组,从0开始
dp[0] = 0; // 初始化dp[0]
dp[1] = volumes[0]; // 只有一瓶酒
if (N >= 2) {
dp[2] = max(volumes[0], volumes[1]); // 有两瓶酒
}
for (int i = 3; i <= N; i++) {
dp[i] = max(volumes[i-1] + dp[i-2], dp[i-1]); // 递推关系
}
return dp[N];
}
int main() {
int N;
scanf("%d", &N);
int volumes[700];
for (int i = 0; i < N; i++) {
scanf("%d", &volumes[i]);
}
int result = maxDrinkingVolume(volumes, N);
printf("%d\n", result);
return 0;
}
程序首先使用scanf
函数从标准输入读取酒瓶的数量N。
然后,使用一个循环从标准输入读取每个酒瓶的体积,并将它们存储在一个名为volumes
的数组中。
调用maxDrinkingVolume
函数,传递酒瓶体积数组和酒瓶数量作为参数,计算最大的喝酒总体积。
在maxDrinkingVolume
函数中,定义一个名为dp
的数组,用于存储动态规划的结果。
根据递推关系,使用一个循环从3到N,计算dp[i]
的值。
最后,返回dp[N]
作为喝的酒的最大总体积。
在主函数中,使用printf
函数输出计算得到的结果。
例如,如果输入为6
,表示有6个酒瓶,然后依次输入6个酒瓶的体积。
程序将计算喝的酒的最大总体积,并输出。
根据给定的数据,喝的酒的最大总体积为33,输出"33"。
阿福是一名经验丰富的大盗。趁着月黑风高,阿福打算今晚洗劫一条街上的店铺。
这条街上一共有 N 家店铺,每家店中都有一些现金。阿福事先调查得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警察就会蜂拥而至。
作为一向谨慎作案的大盗,阿福不愿意冒着被警察追捕的风险行窃。他想知道,在不惊动警察的情况下,他今晚最多可以得到多少现金?
时间限制:1000
内存限制:65536
输入
输入的第一行是一个整数 T (T <= 50) ,表示一共有 T 组数据。 接下来的每组数据,第一行是一个整数 N (1 <= N <= 100, 000) ,表示一共有 N 家店铺。第二行是 N 个被空格分开的正整数,表示每一家店铺中的现金数量。每家店铺中的现金数量均不超过 1000 。
输出
对于每组数据,输出一行。该行包含一个整数,表示阿福在不惊动警察的情况下可以得到的现金数量。
样例输入
2
3
1 8 2
4
10 7 6 14
样例输出
8
24
提示
对于第一组样例,阿福选择第 2 家店铺行窃,获得的现金数量为 8 。 对于第二组样例,阿福选择第 1 和 4 家店铺行窃,获得的现金数量为 10 + 14 = 24 。
以下是使用C语言编写的解决方案:
#include
int max(int a, int b) {
return (a > b) ? a : b;
}
int maxCash(int cash[], int N) {
int dp[100002]; // dp数组,从0开始
dp[0] = 0; // 初始化dp[0]
dp[1] = cash[0]; // 只有一家店铺
if (N >= 2) {
dp[2] = max(cash[0], cash[1]); // 有两家店铺
}
for (int i = 3; i <= N; i++) {
dp[i] = max(cash[i-1] + dp[i-2], dp[i-1]); // 递推关系
}
return dp[N];
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
int N;
scanf("%d", &N);
int cash[100000];
for (int i = 0; i < N; i++) {
scanf("%d", &cash[i]);
}
int result = maxCash(cash, N);
printf("%d\n", result);
}
return 0;
}
程序首先使用scanf
函数从标准输入读取数据组数T。
然后,使用一个循环对每组数据进行处理。
在每次循环中,使用scanf
函数从标准输入读取店铺数量N。
然后,使用一个循环从标准输入读取每家店铺的现金数量,并将它们存储在一个名为cash
的数组中。
调用maxCash
函数,传递现金数量数组和店铺数量作为参数,计算阿福可以得到的最大现金数量。
在maxCash
函数中,定义一个名为dp
的数组,用于存储动态规划的结果。
根据递推关系,使用一个循环从3到N,计算dp[i]
的值。
最后,返回dp[N]
作为阿福可以得到的最大现金数量。
在主函数中,使用printf
函数输出计算得到的结果。
例如,如果输入为2
,表示有2组数据,然后依次输入每组数据的店铺数量和每家店铺的现金数量。
程序将计算阿福可以得到的最大现金数量,并输出。
根据给定的数据,第一组数据中阿福可以得到的最大现金数量为8,输出"8"。第二组数据中阿福可以得到的最大现金数量为24,输出"24"。
一个核电站有N个放核物质的坑,坑排列在一条直线上。如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质。
任务:对于给定的N和M,求不发生爆炸的放置核物质的方案总数
时间限制:6000
内存限制:131072
输入
只一行,两个正整数N,M( 1 < N < 50,2 ≤ M ≤ 5 )
输出
一个正整数S,表示方案总数。
样例输入
4 3
样例输出
13
以下是使用C语言编写的解决方案:
#include
long long int countArrangements(int N, int M) {
long long int dp[51][6] = {0}; // dp数组,从0开始
dp[0][0] = 1; // 初始化dp[0][0]
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
for (int k = 0; k <= i - j; k++) {
dp[i][j] += dp[k][j - 1]; // 递推关系
}
}
}
long long int sum = 0;
for (int j = 0; j <= M; j++) {
sum += dp[N][j]; // 将所有dp[N][j]的值相加
}
return sum;
}
int main() {
int N, M;
scanf("%d %d", &N, &M);
long long int result = countArrangements(N, M);
printf("%lld\n", result);
return 0;
}
程序首先使用scanf
函数从标准输入读取核电站的坑数量N和连续放置核物质的坑数量M。
调用countArrangements
函数,传递坑数量N和连续放置核物质的坑数量M作为参数,计算不发生爆炸的放置核物质的方案总数。
在countArrangements
函数中,定义一个名为dp
的二维数组,用于存储动态规划的结果。
根据递推关系,使用三个嵌套循环,依次计算dp[i][j]
的值。
最后,将所有dp[N][j]
的值相加,得到方案总数。
在主函数中,使用printf
函数输出计算得到的结果。
例如,如果输入为4 3
,表示核电站有4个坑,连续放置核物质的坑数量为3。
程序将计算不发生爆炸的放置核物质的方案总数,并输出。
根据给定的数据,不发生爆炸的放置核物质的方案总数为13,输出"13"。
N个有差别的盒子(1<=N<=20)。你有A个红球和B个蓝球。0 <= A <= 15, 0 <= B <= 15。球除了颜色没有任何区别。你可以将球放进盒子。一个盒子可以同时放进两种球,也可以只放一种,也可以空着。球不必全部放入盒子中。编程计算有多少种放置球的方法。
时间限制:10000
内存限制:131072
输入
就一行,N,A,B,用空格分开
输出
就一行,输出放置方案总数
样例输入
2 1 1
样例输出
9
以下是使用C语言编写的解决方案:
#include
int countArrangements(int N, int A, int B) {
int dp[21][16][16] = {0}; // dp数组,从0开始
dp[0][0][0] = 1; // 初始化dp[0][0][0]
for (int i = 1; i <= N; i++) {
for (int j = 0; j <= A; j++) {
for (int k = 0; k <= B; k++) {
for (int x = 0; x <= j; x++) {
for (int y = 0; y <= k; y++) {
dp[i][j][k] += dp[i - 1][j - x][k - y]; // 递推关系
}
}
}
}
}
int sum = 0;
for (int j = 0; j <= A; j++) {
for (int k = 0; k <= B; k++) {
sum += dp[N][j][k]; // 将所有dp[N][j][k]的值相加
}
}
return sum;
}
int main() {
int N, A, B;
scanf("%d %d %d", &N, &A, &B);
int result = countArrangements(N, A, B);
printf("%d\n", result);
return 0;
}
程序首先使用scanf
函数从标准输入读取盒子数量N、红球数量A和蓝球数量B。
调用countArrangements
函数,传递盒子数量N、红球数量A和蓝球数量B作为参数,计算放置球的方法总数。
在countArrangements
函数中,定义一个名为dp
的三维数组,用于存储动态规划的结果。
根据递推关系,使用五个嵌套循环,依次计算dp[i][j][k]
的值。
最后,将所有dp[N][j][k]
的值相加,得到放置球的方法总数。
在主函数中,使用printf
函数输出计算得到的结果。
例如,如果输入为2 1 1
,表示有2个盒子,1个红球和1个蓝球。
程序将计算放置球的方法总数,并输出。
根据给定的数据,放置球的方法总数为9,输出"9"。