ZOJ 3741 Eternal Reality [dp]

25 篇文章 0 订阅
6 篇文章 0 订阅

In Academy City, most students have special abilities. Such as Railgun, Teleport, Telekinesis, AIM Stalker and so on. Here, AIM (An Involuntary Movement) is a term used to refer to the phenomenon in which an esper involuntarily produces an invisible energy field around the esper. Different students have different type of AIM dispersion field, so they also have different level of abilities.

Of course, a higher level students can often deal with more issues than a lower level students. To classify the students in Academy City, there are 7 levels in total:

LevelTermDescription
Level 0Person with No PowersMost students of this level can't keep up at school. They might possess some degree of power, but unable to truly control it.
Level 1Person with Low PowersPowers of the degree to bend a spoon, many students belong here.
Level 2Person with Unusual PowersJust like Level 1, powers are not very useful in everyday life.
Level 3Person with Strong PowersThe degree when powers are considered convenient in everyday life, ability-wise this is the Level when one starts to be treated as part of the elite.
Level 4Person with Great PowersPowers of an extent that their owner acquires tactical value of a military force.
Level 5Person with Super PowersPowers of an extent that their owner can fight alone against a military force on equal terms.
Level 6Person with Absolute PowersPowers of an extent that they're considered immeasurable. However, no one can achieve this level, even with the help of Level Upper (it has no effect on persons with super powers). Since this, many institutions have been doing long-term researches about it, such as the Radio Noise Project.

You are a student of level L in Academy City and you are going to take part in a sports competition. The competition consists of N consecutive matches. If you want to get a point in the i-th match, your must reach at least Ai level. According to the rules, you must compete in all matches one by one.

To tell the truth, it won't be easy to compete with so many high-level opponents. Fortunately, you got a special item called Level Upper. Generally, it can increase your level by 1 for a short time. If you use the Level Upper before the i-th match, it's effect will last during the matches [i, i + X - 1]. But it also has a side effect that will make your level become 0 during the matches [i + X, i + X + Y - 1]. After the side effect ends, your level will return to L and you can use the Level Upper again.

Please calculate the maximal points you can get if you properly use the Level Upper.

Input

There are multiple test cases (plenty of small cases with several large cases). For each test case:

The first line contains four integers L (0 <= L <= 5), N, X and Y (1 <= N, X, Y <= 100). The next line contains N integers Ai (0 <= Ai <= 6).

Output

For each test case, output the maximal points you can get.

Sample Input
3 6 1 2
1 3 4 5 6 4
Sample Output
4
Hint

Read the problem description carefully.



题意:有n个关卡,每关一个难度ai,一个等级为L的人要连续闯关,当L>=ai时他就可以得1分,否则不得分(继续下一关)。喝一次药可以使他的等级+1,持续x关,之后会出现副作用,他的等级变成0,持续y关,再过后又回复正常,可以继续喝药。问他最多得多少分。关卡难度有0~6,人的等级L为0~5。

注意一点,就算喝药也不能到达6级!!


d[i][j]表示前i关,最后一次在第j关喝药可以得到的最高分。


d[i][j] = d[i-1][j] + 第i关得分(视药效情况)      , j < i

d[i][i] = max{ d[i-1][k] } + (L+1 >= a[i])     , k <= i - x - y



一开始判断如果L等于5那就直接统计难度小于等于5的关卡数就行。



#include<cassert>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<set>
#include<queue>
#include<map>
using namespace std;
#define rep(i,f,t) for(int i = (f), _end = (t); i <= _end; ++i)
#define clr(c,x) memset(c,x,sizeof(c));
#define debug(x) cout<<"debug  "<<x<<endl;
const int INF = 0x3f3f3f3f;
typedef long long int64;
//*******************************************************************************

const int maxn = 110;
int a[maxn];
int d[maxn][maxn];


int main(){
    //freopen("3741.in","r",stdin);
    int lv,n,x,y;
    while(~scanf("%d%d%d%d",&lv,&n,&x,&y)){
        rep(i,1,n) scanf("%d",a+i); 
        if(lv == 5){
            int ans = 0;
            rep(i,1,n)if(a[i] <= 5)++ans;
            printf("%d\n",ans);
            continue;
        }

        d[1][0] = (lv >= a[1]);
        d[1][1] = (lv+1 >= a[1]);
        rep(i,2,n){
            d[i][0] = d[i-1][0] + (lv >= a[i]);   //d[i][0]表示从没喝药
            rep(j,1,i-1){
                d[i][j] = d[i-1][j];
                if(i < j+x)
                    d[i][j] += (lv+1 >= a[i]);        //有效期
                else if(i < j+x+y)
                    d[i][j] += (0 >= a[i]);          //副作用期
                else
                    d[i][j] += (lv >= a[i]);          //已经回复正常
            }
            d[i][i] = d[i-1][0] + (lv+1 >= a[i]);
            rep(k,1,i-x-y){
                d[i][i] = max( d[i][i], d[i-1][k] + (lv+1 >= a[i]) );
            }
        }

        int ans = 0;
        rep(j,0,n){
            ans = max(ans, d[n][j]);
        }
        printf("%d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值