zoj 3741 Eternal Reality(DP)

题意:以魔禁为背景的题~你是学院都市的一个学生,并且你是level L的能力者,现在要接连参加n场比赛,每场比赛你至少要到达level Ai才能得到一分,现在你有一个能增加自身等级的药,每次使用会让你在[i, i + X - 1]场比赛中level变成L+1,但是这个药有副作用,每次使用以后,在[i + X, i + X + Y - 1]场比赛等级会降为0,成为无能力者。。。每次副作用后才能再次使用。。。问最后能获得的最大的分是多少。


思路:还算比较好想的dp吧,但是有个小坑,那就是题中说没有人能到达level 6,因此level 5使用药是无意义的,如果L==5,那么单独处理就好了。。用dp[i][j]表示当前是第i场比赛,上一次在第j场比赛使用了药,j==0表示一直没用过,剩下dp方程挺好想的,就是要讨论下当前的状态,能否用药和当前等级。。最后取最大值就行了,具体看代码吧


代码:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=100+10;
int dp[maxn][maxn],a[maxn];
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int L,n,X,Y;
    while(~scanf("%d%d%d%d",&L,&n,&X,&Y))
    {
        for(int i=1;i<=n;++i)
            scanf("%d",&a[i]);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;++i)
        {
            dp[i][0]=dp[i-1][0]+(L>=a[i]);
            dp[i][i]=max(dp[i][i],dp[i-1][0]+(L+1>=a[i]));
            for(int j=1;j<i;++j)
            {
                if(j+X+Y-1<i)  //可以使用
                {
                    //使用
                    dp[i][i]=max(dp[i][i],dp[i-1][j]+((L+1)>=a[i]));
                    //不使用
                    dp[i][j]=max(dp[i-1][j]+(L>=a[i]),dp[i][j]);
                }
                else          //不能使用
                {
                    if(j+X-1>=i)   //leveruper
                    {
                        dp[i][j]=max(dp[i][j],dp[i-1][j]+((L+1)>=a[i]));
                    }
                    else
                    {
                        dp[i][j]=max(dp[i][j],dp[i-1][j]+(a[i]<=0));
                    }
                }
            }
        }
        int ans=0;
        for(int i=0;i<=n;++i)
            ans=max(dp[n][i],ans);
        if(L==5)
        {
            ans=0;
            for(int i=1;i<=n;++i)
                if(a[i]<=5) ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(dp,ZOJ)