首页 > 其他分享 >Educational Codeforces Round 137 (Rated for Div. 2) - E. FTL

Educational Codeforces Round 137 (Rated for Div. 2) - E. FTL

时间:2022-10-19 14:33:30浏览次数:78  
标签:__ Educational Rated int ll Codeforces cd int128 时刻

DP

Problem - E - Codeforces

题意

有个 BOSS 有 \(H\;(1<=H<=5000)\) 血量,\(s\) 点防御

有两种武器可用攻击 BOSS,伤害分别为 \(p_1,p_2\;(s<min(p_1,p_2)<=5000)\), 冷却时间分别为 \(t_1,t_2\;(1<=t_1,t_2<=10^{12})\)

每一时刻如果 cd 好了可以选择攻击,造成 \(p_i-s\) 点伤害;如果两个武器一起攻击可以造成 \(p_1+p_2-s\) 点伤害

0 时刻两个武器都刚进入 cd,求将 BOSS 消灭的最短时间

思路

  1. 可以选择攻击的时刻一定是 \(p_1\) 或 \(p_2\) 的倍数,并且每次至少造成 1 点伤害,因此最多有 \(H\) 个需要抉择的时刻 \(T_i\)
  2. 当某时刻两个武器同时发射时,之后的操作就成了一个子问题
  3. 可以设 \(f[h]\) 为两个武器都刚进入 cd,打掉 h 血的最短时间,枚举 \(T_i\), 作为第一次刻意等待令两个武器同时发射的时刻,求出前 \(T_i\) 时间正常操作(即 cd 好了就放)造成的伤害 \(tot\), \(f[h]=min(f[h],f[h-tot]+T_i)\)

代码

#include <bits/stdc++.h>
using namespace std;
#define endl "\n"

typedef long long ll;
typedef pair<int, int> PII;

const int N = 5e3 + 10;
int p[3], H, s;
ll t[3], cnt[3];
ll f[N];
vector<ll> vt;
ll lcm(__int128 a, __int128 b)
{
	__int128 t = a / __gcd(a, b) * b;
	if (t >= (__int128)2e18)
		t = 2e18;
	return t;
}

void presolve()
{
	if (t[1] > t[2])
	{
		swap(t[1], t[2]);
		swap(p[1], p[2]);
	}
	p[0] = p[1] + p[2] - s;
	p[1] -= s, p[2] -= s;
	t[0] = lcm(t[1], t[2]);
	for (int i = 1; i * p[1] <= H; i++)
		vt.push_back(i * t[1]);
	for (int i = 1; i * p[2] <= H; i++)
		vt.push_back(i * t[2]);
	sort(vt.begin(), vt.end());
	vt.erase(unique(vt.begin(), vt.end()), vt.end());
}

void solve()
{
	memset(f, 0x3f, sizeof f);
	f[0] = 0;
	for (int h = 1; h <= p[1]; h++)
		f[h] = t[1];
	for (int h = p[1] + 1; h <= H; h++)
	{
		for (auto T : vt)
		{
			if (T % t[0] == 0)
			{
				cnt[0] = T / t[0];
				cnt[1] = T / t[1] - cnt[0];
				cnt[2] = T / t[2] - cnt[0];
			}
			else if (T % t[1] == 0)
			{
				if (T < t[2])
				{
					cnt[1] = T / t[1];
					cnt[2] = cnt[0] = 0;
				}
				else
				{
					cnt[1] = T / t[1];
					cnt[2] = T / t[2];
					ll TT = (cnt[2] - 1) * t[2];
					cnt[0] = TT / t[0] + 1;
					cnt[1] -= cnt[0], cnt[2] -= cnt[0];
				}
			}
			else
			{
				cnt[2] = T / t[2];
				cnt[1] = T / t[1];
				ll TT = (cnt[1] - 1) * t[1];
				cnt[0] = TT / t[0] + 1;
				cnt[1] -= cnt[0], cnt[2] -= cnt[0];
			}
			ll tot = 0;
			for (int i = 0; i < 3; i++)
				tot += cnt[i] * p[i];
			ll now = 0;
			if (tot >= h)
				now = T;
			else
				now = T + f[h - tot];
			f[h] = min(f[h], now);
		}
	}
}

int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> p[1] >> t[1] >> p[2] >> t[2] >> H >> s;
	presolve();
	solve();
	ll ans = f[H];
	cout << ans << endl;
    return 0;
}

标签:__,Educational,Rated,int,ll,Codeforces,cd,int128,时刻
From: https://www.cnblogs.com/hzy717zsy/p/16806108.html

相关文章

  • Codeforces Round #712 A
    A.BalancetheBits显然对于一个字符串s我们每一对0之间必须是()一个合法的括号才行)(也可以显然是等价的因为你a拿前者b就会拿后者所以这就要求了我们0的个数必须是偶......
  • Educational Codeforces Round 107 D
    D.MinCostString显然我们对于每两个组都要本质不同我们考虑本质不同两个组的数量为k^2我们考虑如何构造将这k^2的连接起来不然显然如果一个借着一个显然会产生新的......
  • Codeforces Round #713 E
    E.PermutationbySum显然轻松上下界判断考虑如何构造我们将它整成最小的样子1234....k个从后往前要是他需要我们就直接加上去就可以了#include<bits/stdc++.h......
  • Divide by Zero 2021 and Codeforces Round #714 C
    C.AddOne显然对于每一位单独分析我们经过一次进位只能变成10这样该怎么做呢我们显然可以dp设dp[i][j]表示i(0-9)经过j次变换有几位显然我们初始化i+j<10就是1elsed......
  • Codeforces Round #757 (Div. 2) - D2. Divan and Kostomuksha (hard version)
    GCD+DP+调和级数/埃式筛[Problem-D-Codeforces](https://codeforces.com/contest/1610/problem/D)题意给出一个长度为\(n\;(1<=n<=10^5)\)的数组\(a[i]\;(1<......
  • Codeforces Round #828 (Div. 3) E1. Divisible Numbers (easy version)(数学/暴力)
    https://codeforces.com/contest/1744/problem/E1题目大意:给定a,b,c,d;让我们选择从(a,b]中选出一个x,在(c,d]中选出一个y;满足(x*y)/(a*b)是一个整数。input51......
  • mybatis_25_设置(settings)_useGeneratedKeys
    useGeneratedKeys允许JDBC支持自动生成主键,需要数据库驱动支持。如果设置为true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作。值:true/false(......
  • Educational Codeforces Round 137 (Rated for Div. 2)题解
    比赛链接A.Password大水题,求个组合数就水掉了。点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineN1000010#definelllonglongtemplate<c......
  • Educational Codeforces Round 137 (Rated for Div. 2)
    A.Password计算出现的数,从这些数中任意选两不同的,每种组合6种方案,计算输出即可#include<bits/stdc++.h>usingnamespacestd;intmain(){intt;cin>>t;......
  • Codeforces 977D. Divide by three, multiply by two
    Dividebythree,multiplybytwoPolycarplikestoplaywithnumbers.Hetakessomeintegernumberx,writesitdownontheboard,andthenperformswithitn−1......