hdu 3905 Sleeping

http://acm.hdu.edu.cn/showproblem.php?pid=3905

dp + 记忆化搜索

把 M 和 L 弄反了  wa 了N久  我彻底无语了

关键思路:

在学了 L 之后如果想继续学 在学的时间无需大于等于 L

代码及其注释:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<string>

#include<vector>

#include<queue>

#include<map>

#include<stack>

#include<algorithm>

#include<cmath>



using namespace std;

//#pragma comment(linker,"/STACK:1000000000,1000000000")



#define LL long long



const int INF=0x3f3f3f3f;

const int N=1005;

int ansL[N][N];// 前 i 的时间内 至少需要睡 j 分钟 如果学习要至少L 时间 的最优结果

int ans1[N][N];// 前 i 的时间内 至少需要睡 j 分钟 如果学习 可以时间任意 的最优结果

int sum[N];// 前 i 项和

int a[N];// 某个时间点的值

int n,L,M;

int dp1(int ,int);

int dpL(int i,int j)

{

    if(ansL[i][j]!=-1)

    return ansL[i][j];

    ansL[i][j]=0;//最少获得 0 值

    if(j==0)

    {

        if(i>=L)// 这时候 剩余量时间在大于等于L的情况下 才可以全部获得

        ansL[i][j]=sum[i];

        return ansL[i][j];

    }

    if(j-1<=i-1)

    ansL[i][j]=dpL(i-1,j-1);//此时间点睡觉

    if(j<=i-L)

    ansL[i][j]=max(ansL[i][j],sum[i]-sum[i-L]+dp1(i-L,j));//学习L时间(然后再学的话 时间不受限制)

    return ansL[i][j];

}

int dp1(int i,int j)

{

    if(ans1[i][j]!=-1)

    return ans1[i][j];

    ans1[i][j]=0;

    if(j==0)

    return (ans1[i][j]=sum[i]);

    if(j-1<=i-1)

    ans1[i][j]=dpL(i-1,j-1);//此时间点睡觉

    if(j<=i-1)

    ans1[i][j]=max(ans1[i][j],a[i]+dp1(i-1,j));//此时间点学习

    return ans1[i][j];

}

int main()

{

    //freopen("data.txt","r",stdin);

    while(scanf("%d %d %d",&n,&M,&L)!=EOF)

    {

        memset(ansL,-1,sizeof(ansL));

        memset(ans1,-1,sizeof(ans1));

        for(int i=1;i<=n;++i)

        scanf("%d",&a[i]);

        sum[0]=0;

        for(int i=1;i<=n;++i)

        {

            sum[i]=a[i]+sum[i-1];

        }

        printf("%d\n",dpL(n,M));

    }

    return 0;

}

 

你可能感兴趣的:(sleep)