题意:以魔禁为背景的题~你是学院都市的一个学生,并且你是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; }