洛谷p2392-考前临时抱佛脚 (搜索)(01背包)

题目传送

kkksc03考前临时抱佛脚

题目分析

题目难度:普及-
4科的习题集每1科的计算方法都是一样的,研究一科的题集即可。
本题要注意的是kkk的脑子可以同时计算两个题目,所以从深度优先搜索的角度来看每一个题目都有两种选择,去左脑or右脑。很显然当所有题目都集中到一边的时候花费时间是最大的,然后再一科一科的往另一边放,逐渐减少时间的花费。经过分析可以得出,每一科的习题集所花费的最少时间为 总花费的一半,不能再少了!当所有数都放完后,取两边脑子的最大值,同时枚举选出所有最大值中的最小值,即为答案。本题数据量最大为20,所以暴力搜索的时间复杂度为 10的6次方

由此可以采用01背包的思想来解题!

设一背包的容量为总时间花费的一半 t/2,那么要放的物品就是一科的所有题目,其价值与重量即为花费的时间,
求在不超过背包容量的前提下,最多能放入物品的总价值w,然后用总时间t减去w即为本科目花费的最少时间。

AC代码

#include
#include
#include
#include
#include 
#include
#include
#include
#include 
#include

using namespace std;


int a[4][30];
int s[4];
int minn;
int Left,Right;

//dfs的暴力搜索,对每一组数据中的每一个数,都有两个选择,来左边脑子或者是右边
//优化思想是当某一边脑子的数值和最接近本组数组和的一半时,另一边脑子的值就是答案
//如果不知道这个思想,可以直接暴力搜索,所有的数值都放到左边脑子,然后依次往右边加
//当所有数都放完后,取两边脑子的最大值,同时枚举选出所有最大值中的最小值,即为答案
//本题数据量最大为20,所以暴力搜索的时间复杂度为 10的6次方 
void dfs(int i,int j)
{ //第j组数据,中的第i个数 
	if(i==s[j]+1)
		{
			minn = min(minn,max(Left,Right));
			return;  //返回,然后继续下一种方案 
		}	
		
	Left += a[j][i];
	dfs(i+1,j);
	Left-=a[j][i]; //回溯 

	Right +=a[j][i];
	dfs(i+1,j);
	Right-=a[j][i];
	
	return ;
}
int main()
{
	int t=0;
	for(int i=0;i<4;i++)
		cin>>s[i];
		
	for(int j=0;j<4;j++)
	{
	for(int i=0;i<s[j];i++)
		{
		cin>>a[j][i];
		}
	minn = 0x3f3f3f3f;
	Left = Right = 0;
	dfs(0,j);
	t += minn;
	}
	cout<<t;
	return 0;
} 
#include
#include
#include
#include
#include 
#include
#include
#include
#include 
#include

using namespace std;

int a[4][30];  //四科习题,对应的题目 
int s[4];  //每科习题的题目数量 
int ans; //最终消耗的最小时间 
int dp[3000];//表示容量为j的背包最多能容纳的价值(即脑子一边作为一个背包,容量为 t/2
		  //即是题目总耗费时间的一半,然后把这些所有的题目往里面放,在不超过容量的
		  //的前提下求能够放进去的最大题目耗费时间,然后另一边脑子的题目耗费时间总数
		  //即为本组习题集所花费的时间! 
int main()
{
	for(int i=0;i<4;i++)	
		cin>>s[i];
	for(int i=0;i<4;i++)
	{
		int t=0;
		for(int j=1;j<=s[i];j++)
			{
			cin>>a[i][j]; //每个物品的容量,同时也是价值 
			t+=a[i][j];  //背包容量的二倍 
			}
		for(int k=1;k<=s[i];k++) //表示1 - s[i]个物品(即题目) 
			for(int j=t/2; j>=a[i][k];j--) //背包容量 逆序 遍历
				dp[j] = max(dp[j],dp[j-a[i][k]]+a[i][k]);   //注意k的下标!!! 
					
		ans+=(t-dp[t/2]);	
		for(int j=0;j<=t/2;j++)
			dp[j] = 0; 
	}
	cout<<ans;
} 	



你可能感兴趣的:(搜索)