临时抱佛脚问题就是在n门科目中完成每门科目的k个题目,并且每门科目可以同时写两道题目,求完成复习的最短时间。下面举例洛谷p2392
直接上代码,来,无脑输入m门科目,用for循环输入每门科目的题目数量。代码如下:
for(int i=1;i<=4;i++)
cin>>a[i];
for(int i=1;i<=4;i++)
for(int j=1;j<=a[i];j++)
{
cin>>w[i][j];
}
然后应该怎么样去做这道题呢?我们可以运用递归思想,首先我们可以将左脑,右脑,需要做的步骤,做几次,传递参数给dfs这个函数,那么由题可知,有n门科目,就需要运行n次。代码如下:
for(int i=1;i<=4;i++)
dfs(0,0,0,i);
那关键就是dfs怎么写代码,首先做出终止条件的判定,就是当步骤step等于a[n]意味着已经找完了所有的数,找出左脑和右脑的最大值,然后再将找出的这个最大值去和1200比较,为什么跟1200去比较呢?因为题目最多为20门科目,每门科目最多60个题目,所以最多只有1200情况。记得写return;如果没有终止就使得step每次加1,进行递归,既可以左边也可以右边递归,代码如下:
void dfs(int left,int right,int step,int n)
{
if(step==a[n])
{
int t=max(left,right);
if(t<b[n])
b[n]=t;
return ;
}
step++;
dfs(left,w[n][step]+right,step,n);
dfs(w[n][step]+left,right,step,n);
}
总代码如下:
#include <iostream>
using namespace std;
int a[5],w[5][65];
int t=0,ans=0;
int b[5]={0,1200,1200,1200,1200};
void dfs(int left,int right,int step,int n)
{
if(step==a[n])
{
int t=max(left,right);
if(t<b[n])
b[n]=t;
return ;
}
step++;
dfs(left,w[n][step]+right,step,n);
dfs(w[n][step]+left,right,step,n);
}
int main()
{
for(int i=1;i<=4;i++)
cin>>a[i];
for(int i=1;i<=4;i++)
for(int j=1;j<=a[i];j++)
{
cin>>w[i][j];
}
for(int i=1;i<=4;i++)
dfs(0,0,0,i);
for(int i=1;i<=4;i++)
ans+=b[i];
cout<<ans;
return 0;
}