【CF】CF1430_F Realistic Gameplay_dp

链接

codeforces 1430F

题面

【CF】CF1430_F Realistic Gameplay_dp

题解

  • 我们记第i波的实际控制范围为\([l_i,\min(r_i,l_{i+1}-1]\)。记\(f_i\)表示在第i波实际控制范围内把前面的所有怪物都打死至少浪费多少子弹。
  • 每次直接\(O(n)\)往后转移即可。
  • 实际上是可以不用\(r_i\leq l_{i+1}\)的,只用保证\(l_i\leq l_{i+1},r_i\leq r_{i+1}\)。

代码

#include<bits/stdc++.h>
#define LL long long
#define MAXN 2010
#define INF 100000000000000
using namespace std;
template<typename T> void Read(T &cn)
{
	char c; int sig = 1;
	while(!isdigit(c = getchar())) if(c == '-') sig = 0;
	if(sig) {cn = c-48; while(isdigit(c = getchar())) cn = cn*10+c-48; }
	else    {cn = 48-c; while(isdigit(c = getchar())) cn = cn*10+48-c; }
}
template<typename T> void Write(T cn)
{
	int wei = 0; T cm = 0; int cx = cn%10; cn/=10;
	if(cn < 0 || cx < 0) {putchar('-'); cn = 0-cn; cx = 0-cx; }
	while(cn)cm = cm*10+cn%10,cn/=10,wei++;
	while(wei--)putchar(cm%10+48),cm/=10;
	putchar(cx+48);
}
template<typename T> void WriteL(T cn) {Write(cn); puts(""); }
template<typename T> void WriteS(T cn) {Write(cn); putchar(' '); }
template<typename T> void Max(T &cn, T cm) {cn = cn < cm ? cm : cn; }
template<typename T> void Min(T &cn, T cm) {cn = cn < cm ? cn : cm; }
int n;
LL k;
int a[MAXN+1], l[MAXN+1], r[MAXN+1];
LL f[MAXN+1];
int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	Read(n); Read(k);
	for(int i = 1;i<=n;i++) Read(l[i]), Read(r[i]), Read(a[i]);
	for(int i = 1;i<=n;i++) f[i] = INF; f[0] = 0;
	for(int i = 0;i<=n-1;i++)
	{
//		printf("f[%d] = %lld\n",i,f[i]);
		int lef_bu = k, lef_mo = 0;
		for(int j = i+1;j<=n;j++)
		{
			if(lef_bu+k*(r[j]-l[j]) < lef_mo+a[j]) break;
			if(j == n) {Min(f[j], f[i]); break; }
			int br = min(l[j+1]-1, r[j]);
			if(lef_bu+k*(br-l[j]) >= lef_mo+a[j]) {
				lef_bu = (lef_bu+k*(br-l[j])-lef_mo-a[j])%k, lef_mo = 0;
				if(lef_bu == 0) lef_bu = k;
				Min(f[j], f[i]+lef_bu);
			}
			else {
				if(r[j] == l[j]) lef_mo = lef_mo+a[j];
				else lef_mo = lef_mo+a[j]-lef_bu-k*(br-l[j]), lef_bu = k;
			}
//			printf("  j = %d lef_mo = %d lef_bu = %d\n",j,lef_mo,lef_bu);
		}
	}
	if(f[n] >= INF) {puts("-1"); return 0; }
	for(int i = 1;i<=n;i++) f[n] = f[n]+a[i];
	WriteL(f[n]);
	return 0;
}
上一篇:【逐帧分析】《黑神话:悟空》gameplay相关的技术和调整细节整理


下一篇:⭐算法入门⭐《二叉树 - 二叉搜索树》简单08 —— LeetCode 938. 二叉搜索树的范围和