我是靠谱客的博主 花痴含羞草,最近开发中收集的这篇文章主要介绍P4953 [USACO02FEB]Cow Cycling,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

        • R e s u l t Result Result
        • H y p e r l i n k Hyperlink Hyperlink
        • D e s c r i p t i o n Description Description
        • S o l u t i o n Solution Solution
        • C o d e Code Code

R e s u l t Result Result

...


H y p e r l i n k Hyperlink Hyperlink

https://www.luogu.com.cn/problem/P4953


D e s c r i p t i o n Description Description

n n n头初始体力为 E E E的奶牛,它们要跑 D D D
每一分钟,它们可以选择一个速度 k k k,并选出一头牛 x x x领跑,必须满足领跑的这头牛不会再领跑期间体力耗尽
在这一分钟里,它们将跑过 k k k圈,领跑这头牛的体力将减少 k 2 k^2 k2,其它牛的体力将减少 k k k
如果体力不大于0,标明这头牛已经掉队了,后续不再考虑它
领跑这头牛不能在领跑期间掉队(但你可以更改领跑的牛,不过必须隔一分钟【每一分钟为单位选出一个新的领跑,当然也可以不变】)
问至少有一头牛到达终点时不掉队【或者恰好掉队也行,在物理上它等价于恰好不掉队】的最小时间

数据范围: n ≤ 20 , E ≤ 100 , D ≤ 100 nleq 20,Eleq 100,Dleq 100 n20,E100,D100


S o l u t i o n Solution Solution

d p dp dp
首先可以证明让牛尽量接替着领跑显然不会更劣,因此我们每次只关心上一次领跑的牛是哪个

由于我们需要一头牛在剩余体力为某个值的情况下,跑若干圈的最少时间
所以我们可以设 g i , j g_{i,j} gi,j表示剩余体力为 i i i,跑 j j j圈的最少时间
初态显然是 g i , 0 = 0 g_{i,0}=0 gi,0=0
枚举领跑的速度 k k k,显然有 g i , j = m i n { g i − k 2 , j − k + 1 } g_{i,j}=min{g_{i-k^2,j-k}+1} gi,j=min{gik2,jk+1}

接下来要求 n n n头牛跑完 D D D圈的最少时间
f i , j f_{i,j} fi,j表示 i i i头牛跑完 j j j圈的最少时间,我们只需要枚举上一次领跑的牛领跑 k k k
初态显然是 f 0 , 0 = 0 f_{0,0}=0 f0,0=0
因为在这头领跑的牛领跑之前,它已经跟着其它牛【换言之被领跑了】 D − j D-j Dj圈,所以它现在的体力是 E − ( D − j ) E-(D-j) E(Dj)
有转移 f i , j = m i n { f i − 1 , j − k + g E − ( D − j ) , k } f_{i,j}=min{f_{i-1,j-k}+g_{E-(D-j),k}} fi,j=min{fi1,jk+gE(Dj),k}

终态显然是 f n , D f_{n,D} fn,D
复杂度为 O ( E 1.5 D + n D 2 ) O(E^{1.5}D+nD^2) O(E1.5D+nD2)


C o d e Code Code

#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;int n,E,D,g[101][101],f[11][101];
inline LL read()
{
	char c;LL d=1,f=0;
	while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
	while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
	return d*f;
}
signed main()
{
	n=read();E=read();D=read();
	memset(g,0x3f,sizeof(g));
	for(register int i=0;i<=E;i++) g[i][0]=0;
	for(register int i=1;i<=E;i++)
	 for(register int j=1;j<=D;j++)
	  for(register int k=1;k*k<=i&&k<=j;k++) g[i][j]=min(g[i][j],g[i-k*k][j-k]+1);
	memset(f,0x3f,sizeof(f));
	f[0][0]=0;
	for(register int i=1;i<=n;i++)
	 for(register int j=0;j<=D;j++)
	  for(register int k=0;k<=j;k++) f[i][j]=min(f[i][j],f[i-1][j-k]+g[E-(D-j)][k]);
	printf("%d",f[n][D]);
}

最后

以上就是花痴含羞草为你收集整理的P4953 [USACO02FEB]Cow Cycling的全部内容,希望文章能够帮你解决P4953 [USACO02FEB]Cow Cycling所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部