AcWing 288. 休息时间 滚动数组+分类讨论

//f[i,j,0],考虑了前i小时,且一共睡了j小时,且第i小时不睡觉的最大收益
//f[i,j,1],考虑了前i小时,且一共睡了j小时,且第i小时在睡觉的最大收益
//f[i,j,0]=max{f[i-1,j,0],f[i-1,j,1]}
//f[i,j,1]=max{f[i-1,j-1,0],f[i-1,j-1,1]+w[i]}
//第N小时不在睡觉的话 
//f[1,1,0]=0,f[1,1,1]=0
//答案:f[N,B,0]
//第N小时在睡觉的话 
//f[1,1,0]=0,f[1,1,1]=w[1] 
//答案:f[N,B,1]
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=4040,INF=0x3f3f3f3f;
int n,m;
int f[2][N][2];
int w[N];
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>w[i];
	memset(f,-0x3f,sizeof f);
	//第N小时不在睡觉
	f[1][0][0]=f[1][1][1]=0;
	for(int i=2;i<=n;i++)
		for(int j=0;j<=m;j++)
		{
			f[i&1][j][0]=max(f[i-1&1][j][0],f[i-1&1][j][1]);
            f[i&1][j][1]=-INF;
            if(j) 
				f[i&1][j][1]=max(f[i-1&1][j-1][0],f[i-1&1][j-1][1]+w[i]);
		}
	int res=f[n&1][m][0];
	memset(f,-0x3f,sizeof f);
	//第N小时在睡觉
	f[1][1][1]=w[1];
    f[1][0][0]=0;
	for(int i=2;i<=n;i++)
		for(int j=0;j<=m;j++)
		{
			f[i&1][j][0]=max(f[i-1&1][j][0],f[i-1&1][j][1]);
            f[i&1][j][1]=-INF;
            if(j) 
				f[i&1][j][1]=max(f[i-1&1][j-1][0],f[i-1&1][j-1][1]+w[i]);
		}
	res=max(f[n&1][m][1],res);
	cout<<res<<endl;
	return 0;
}
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12575436.html