概述
文章目录
- 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 n≤20,E≤100,D≤100
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{gi−k2,j−k+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
D−j圈,所以它现在的体力是
E
−
(
D
−
j
)
E-(D-j)
E−(D−j)
有转移
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{fi−1,j−k+gE−(D−j),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所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复