题目传送门:https://www.luogu.org/problem/show?pid=3040
主要思路:这道题开始我是写的爆搜,后来T了4个点,我就开始思考能不能写DP.
然后我写了一个四维的记搜,想着用空间来换时间,结果很操蛋的MLE了.
爱思考的我又开始想:能不能压一下维度呢?
我们可以发现:因为每次必须要放干草,所以我们只要知道前两个牧场的干草总数,就能求出第3个牧场的干草数.
这样空间复杂度低了不少.PS:比我基友读秒的深搜还要跑的快!
我们可以用一个数组来储存每一秒的干草总数.
状态转移方程就很舒服的出来了:
又PS:step是现在的时间,x是第一个牧场的干草数,y是第二个的.
DP[step][x][y]=max(DP[step][x+w[step]][y],DP[step][x][y+w[step],DP[step][x][y]);
附上代码:
#include <iostream>
#define MAXN 50
#define MAXM 510
using namespace std;
int w[MAXN],sum[MAXN],dp[MAXN][MAXM][MAXM];
int n;
int minx(int x,int y,int z)
{
return min(x,min(y,z));
}
void init()
{
int i;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>w[i];
sum[i]=sum[i-1]+w[i];
}
return;
}
int search(int step,int x,int y,int z)
{
z=sum[step-1]-x-y;
if(step==n+1)
{
return max(x,max(y,z));
}
if(dp[step][x][y]!=0)
{
return dp[step][x][y];
}
dp[step][x][y]=minx(search(step+1,x+w[step],y,z),search(step+1,x,y+w[step],z),search(step+1,x,y,z));
return dp[step][x][y];
}
void out()
{
cout<<dp[1][0][0];
return;
}
int main()
{
init();
search(1,0,0,0);
out();
return 0;
}</span>