题意:
一个人等级为L , 与n个人对打(当自己等级高于或者和对方相同时自己胜利)
第二行输入n个人的等级
有一个技能可以暂时提升等级(使用后x天内提升一级,技能效果过后y天内进入虚弱等级变为0,并且不能使用技能。再过y天恢复到原先等级)
与n个人从第一天开始按顺序每天与一个人对打一次,问:最多的胜利次数。
(注意:等级5 和等级6 无法使用该技能)
思路:
三维dp
注意0代表的含义。
#include#include #include using namespace std; #define N 101 #define ll int ll L, n, x, y; ll dp[N][2][N], non[N], a[N]; // dp[i][0][j]表示第i天 使用了升级技能后的第j天 的最大值 j=0表示这一天不升级的最大值 // dp[i][1][j]表示第i天 处于虚弱状态的第j天的最大值 j=0表示刚用完技能还没开始休息 int main(){ ll i, j; while(~scanf("%d%d%d%d",&L,&n,&x,&y)){ for(i=1;i<=n;i++)scanf("%d",&a[i]); memset(non, 0, sizeof(non)); memset(dp, 0, sizeof(dp)); for(i=1;i<=n;i++)non[i] = (L>=a[i]) + non[i-1]; if(L==5){printf("%d\n", non[n]);continue;} for(i=1;i<=n;i++) { dp[i][0][0] = non[i]; //不变身 dp[i][0][0] = max(dp[i][0][0], dp[i-1][1][y]+(L>=a[i])); dp[i][0][0] = max(dp[i][0][0], dp[i-1][0][0]+(L>=a[i])); dp[i][0][1] = dp[i][0][0] - (L>=a[i]) + (L+1>=a[i]); for(j = 2; j <= x; j++)dp[i][0][j] = dp[i-1][0][j-1]+(L+1>=a[i]); if(i>=x)dp[i][1][0] = dp[i][0][x]; for(j=1;j<=y;j++)dp[i][1][j] = dp[i-1][1][j-1]+(0>=a[i]); } ll ans = 0; for(j=0;j<=x;j++)ans = max(ans, dp[n][0][j]); for(j=1;j<=y;j++)ans = max(ans, dp[n][1][j]); printf("%d\n",ans); } return 0; } /* 3 6 1 2 1 3 4 5 6 4 6 6 1 2 1 3 4 5 6 4 0 6 1 100 0 0 0 0 0 0 1 4 1 1 1 0 1 0 0 4 1 1 1 1 0 1 0 6 1 2 1 0 1 0 1 1 0 6 1 1 1 2 1 0 1 0 3 10 2 2 1 2 4 4 5 0 5 3 4 1 3 10 2 0 1 2 4 4 5 0 5 3 4 1 3 10 0 2 4 4 4 4 4 4 4 4 4 4 3 10 1 2 4 4 4 4 4 4 4 4 4 4 3 10 1 0 4 4 4 4 4 4 4 4 4 4 3 10 0 0 4 4 4 4 4 4 4 4 4 4 5 1 1 0 6 */