(但例子是对的,应该是边界问题,摆烂了)
玛恩纳有两种状态:
第一种为暖机状态,期间玛恩纳不能攻击。暖机时间为 FF 秒。
第二种为开启技能状态,期间玛恩纳会对攻击范围内所有敌人每秒造成 11 点伤害。技能持续时间为 KK 秒。战斗开始时,玛恩纳可以在任意时刻开启技能。技能结束后,玛恩纳会进入暖机状态。在接下来 FF 秒内,玛恩纳不能攻击。暖机时间结束后,可以继续选择在接下来的某一时刻开启技能。
给出 nn个敌人的在玛恩纳攻击范围的起始时间和结束时间 [L_i,R_i],
特别的所有敌方单位的生命值 H=R_i - L_i + 1H=R
开始时刻为第 1 秒,请问在接下来 T 秒,玛恩纳最多能杀死多少敌方单位。
#include
using namespace std;
int main()
{
int enemy,all_t,fight,rest;
// 获取基本信息
cin >>enemy;
// 敌人数量
cin >> all_t;
// 总时长
cin >> fight;
// 战斗时间
cin >> rest;
// 休息时间
int caifen[all_t]={0};
// 创建拆分数组
int val[all_t]={0};
// value数组
// 如果敌人是在b-fight和a范围内,
// 则可以被击杀
// 那么就可以在value的这个时段+1
// 表示该时段开枪可以杀敌+1
// 利用差分的方法,不用使用两次for循环来在时段里面+1
// 防止超时
for (int i = 0; i < enemy; i++)
{
// 对拆分数组进行操作,如果 在可击杀范围了,开始+1,结束-1
int a,b;
cin >> a;
cin >> b;
if(b-fight<0)
{
// 防止开始时间为负数
caifen[0]++;
}
else
{
caifen[b-fight]++;
}
caifen[a]--;
}
val[0]=caifen[0];
// value的第一个数据和拆分的一样的
// value的第i个数据表示第i秒开枪能击杀的敌人数
for (int i = 1; i < all_t; i++)
{
// 进行前缀和处理,获取完整地value
val[i]=val[i-1]+caifen[i];
}
int res[all_t]={0};
// res数组为动态规划的价值量
// 第i个数据表示第i秒前,全部杀敌数的最大化
res[0] = val[0];
for (int i = 1; i < all_t; i++)
{
if (i <= fight+rest)
// 如果时间是小于第一次战斗+暖机时间,那么就不会存在上一次战斗,也就不用上次的战斗的最优解来进行比较
// 所以可以进行直接比较
{
if(res[i-1]<val[i])
{
res[i]=val[i];
}
else
{
res[i]=res[i-1];
}
}
else
{
if(res[i-1]<val[i]+res[i-fight+rest])
// 对前一次的最优解 和 本次杀敌数以及一个循环前的最优解进行比较
{
res[i]=val[i]+res[i-fight+rest];
}
else
{
res[i]=res[i-1];
}
}
}
cout << res[all_t-1];
}