洛谷——p2392 kkksc03考前临时抱佛脚

今天练习了一些搜索,动态规划的题,只敢选普及-的来做,这个题看上去感觉用贪心来做,而且看上去不知道怎么用背包解题,他的最大“容量”是不确定的。

题目是这样的:

【题目背景】

kkksc03 的大学生活非常的颓废,平时根本不学习。但是,临近期末考试,他必须要开始抱佛脚,以求不挂科。

【题目描述】

这次期末考试,kkksc03 需要考 4 科。因此要开始刷习题集,每科都有一个习题集,分别有 s1​,s2​,s3​,s4​ 道题目,完成每道题目需要一些时间,可能不等(A1​,A2​,…,As1,B1​,B2​,…,Bs2​​,C1​,C2​,…,Cs3​​,D1​,D2​,…,Ds4​​)。

kkksc03 有一个能力,他的左右两个大脑可以同时计算 2 道不同的题目,但是仅限于同一科。因此,kkksc03 必须一科一科的复习。

由于 kkksc03 还急着去处理洛谷的 bug,因此他希望尽快把事情做完,所以他希望知道能够完成复习的最短时间。

【输入】

本题包含 5 行数据:第 11 行,为四个正整数 s1​,s2​,s3​,s4​。

第 2 行,为 A1​,A2​,…,As1​​ 共 s1​ 个数,表示第一科习题集每道题目所消耗的时间。

第 3 行,为 B1​,B2​,…,Bs2​​ 共 s2​ 个数。

第 4 行,为 C1​,C2​,…,Cs3​​ 共 s3​ 个数。

第 5 行,为 D1​,D2​,…,Ds4​​ 共 s4​ 个数,意思均同上。

【输出】

输出一行,为复习完毕最短时间。

样例输入

1 2 1 3		
5
4 3
6
2 4 3

样例输出

20 

 解题思路

这个题分为四组来看,因为题目中:“他的左右两个大脑可以同时计算 2 道不同的题目,但是仅限于同一科。”这四组分别是四个科目。

然后我想的是在同一个科目中,把两个数拿出来比较,比较 n-1 次,记录下每一次之差,第一个差为数组第一个数,比如如果是对于 A 科目,用sum记录最短时间,第一个数是 A[0],计数器sum=sum+A[0],令 k=A[0],把 k 与 A[1] 比较,若A[1]>k, k则重新赋值为 k=A[i]-k,计数器 sum=sum+k;若 A[1]<k,k=k-A[1],计数器不增加,之后的同理。

我运用的贪心的思想,但是这样写出来的代码全是WA,代码如下:

#include<stdio.h>
int main()
{
	int i,a,b,c,d,sum=0,k;
	int A[25],B[25],C[25],D[25];
	//输入每个科目的题数 
	scanf("%d %d %d %d",&a,&b,&c,&d);
	//输入每个科目花费的时间 
	for(i=0;i<a;i++)
	scanf("%d",&A[i]);
	for(i=0;i<b;i++)
	scanf("%d",&B[i]);
	for(i=0;i<c;i++)
	scanf("%d",&C[i]);
	for(i=0;i<d;i++)
	scanf("%d",&D[i]);
	//分别计算出每个科目花费的最短时间 
	k=A[0];
	sum=sum+A[0];
	for(i=1;i<a;i++)
	{
	    if(A[i]>=k)
	    k=A[i]-k;
	    else if(A[i]<k)
	    k=k-A[i];
	    sum=sum+k;
    }
    k=B[0];
    sum=sum+B[0];
	for(i=1;i<b;i++)
	{
		if(B[i]>=k)
		{
			k=B[i]-k;
			sum=sum+k;
		}
		else if(B[i]<k)
		k=k-B[i];
	}
	k=C[0];
    sum=sum+C[0];
	for(i=1;i<c;i++)
	{
		if(C[i]>=k)
		{
			k=C[i]-k;
			sum=sum+k;
		}
		else if(C[i]<k)
		k=k-C[i];
	}
	k=D[0];
    sum=sum+D[0];
	for(i=1;i<d;i++)
	{
		if(D[i]>=k)
		{
			k=D[i]-k;
			sum=sum+k;
		}
		else if(D[i]<k)
		k=k-D[i];
	}
	printf("%d\n",sum);
	return 0;
}

 至于哪里出问题了,应该是数据过大时计算会出问题。

可以试试背包解题,先要解决背包的最大“容量”是多大,再看看题目,如果每个题消耗的时间相加为 sum,这个最短时间 time 是不是一定会大于等于 sum/2 ?因为最凑巧的情况是两个题消耗的时间一样(两个都为 5),sum为 10,这样最短时间 time 正好为 sum/2(5),但是不会出现比 sum/2 更小的情况了。

反过来消耗时间 sum 减去前面所说的最短时间 time,这个 sum-time 是不是就一定小于等于 sum/2 了,这样看来就可以试试用背包求 sum-time,此时背包最大容积为 sum/2,然后要求的答案为:用背包求解得出的,四个dp[sum/2][n]之和。

代码如下:

#include<stdio.h>
int dp[1205][25],sum,k[4],a[25];
//定义全局的 dp 数组和 a 数组 
int max(int x,int y)
{
	if(x>=y)
	return x;
	else
	return y;
}
//用动态规划求解 
void fun(int v,int n)
{
	int i,j;
	//一维遍历题目个数 
	for(j=1;j<=n;j++)
	{
		//二维遍历总和时间的一半,因为这里求的dp最大不会超过sum/2 
		for(i=1;i<=v;i++)
	    {
		    if(i>=a[j])
		    dp[i][j]=max(dp[i][j-1],dp[i-a[j]][j-1]+a[j]);
		    else
		    dp[i][j]=dp[i][j-1];
	    }
	}
}
int main()
{
	int t=0,i,j,b;
	for(i=0;i<4;i++)
	scanf("%d",&k[i]);
	for(j=0;j<4;j++)
	{
		sum=0;
		for(i=1;i<=k[j];i++)
		{
			scanf("%d",&a[i]);
			sum=sum+a[i];
		}
		fun(sum/2,k[j]);
		//每一科目所需的最短时间为sum-dp[sum/2][k[j]] 
		t=t+sum-dp[sum/2][k[j]];
		//在一个科目计算完后,要归零,否则会影响后面科目的计算 
		for(i=0;i<=sum;i++)
		{
			for(b=0;b<=k[j];b++)
			dp[i][b]=0;
		}
	}
	printf("%d\n",t);
	return 0;
} 

总结

用动态规划还是很不熟悉,做这个题目时,把dp数组的一维和二维弄混了,然后出错了,虽然思路基本正确,但是代码没有实现正确,还是得多做有关这个的题目。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 《考试——山东省大数据工程专业技术人员》是一篇介绍山东省大数据工程专业技术人员考试的文章。该考试是为了选拔优秀的大数据工程专业技术人员,提高山东省大数据产业发展和企业竞争力而举办的。 文章指出,考试内容主要包括岗位实际操作能力和专业知识两个部分。岗位实际操作能力考试主要是为了测试考生的实际动手能力和处理问题的能力,包括数据分析能力、编程能力等。而专业知识考试则测试考生对大数据工程相关理论知识和技术应用的理解和掌握程度。 文章提到,为了提高考生的考试成功率,考生需认真准备,并了解考试内容和考试形式。此外,建议考生平时多加练习,不断提高自己的能力和技术水平,为通过考试打下坚实的基础。 综上所述,《考试——山东省大数据工程专业技术人员》介绍了该考试的考试内容和目的,并给予了考生考前的建议和指导,对于准备参加该考试的考生有很好的参考价值。 ### 回答2: 山东省大数据工程专业技术人员考试是针对该领域相关人员的专业技术能力考试,旨在对参加考试的人员掌握这一领域的专业知识、技能和技术应用能力进行检验和评估。 该考试将覆盖大数据基础知识、数据挖掘、数据分析、机器学习、大数据平台建设、大数据处理与存储等多个方面,考察考生对于这些领域的掌握程度。考试类型包括理论知识考试和实践操作考试,通过该考试,可以有效地检验考生的专业素质和技术能力,并为企业更好地选拔和招聘相应人才提供参考依据。 此外,参加山东省大数据工程专业技术人员考试还可以获得相应的考试证书和成绩单,这将有助于考生增强自身的信心和竞争力,在职场中获得更好的职业发展。同时,考试还可以促进考生在大数据领域的学习和掌握,不断提升个人专业水平和发展前景。因此,该考试对于大数据行业从业者来说,是非常重要的一个考试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明里灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值