设f[i][j]:第i只猴子跳到第j棵树的最小劳累值
可以得到
f [ i ][ j ] = min( f[ i ][ ii ] + (d[ j ] >= d[ ii ] ) ) // ii = j - k[ i ]; ii < j;ii ++
再想一想,如果 f[ i ][ jj ]为最小值,那么就算h[i] > h[jj] ,f[ i ][ jj ] + 1 也一定是最小的(可能f[ i ][ jj ] 等于f[i][iii],f[ i ][ jj ] + 1 > f[i][iii],但处理一下就可以了),所以先可以不考虑是否+1,所以可以用一个单调上升序列(s)。因为队头是最小的,所以f[i][j] = f[s[head]] + (h[j] >= h[s[head]]) 。再将f[i][j]进入队列,但这里需要特殊处理一下,如果f[i][j]==f[s[tail]] && h[j] > h[s[tail]]也可将s[tail]踢出序列
参考代码:
for(i = 1;i <= q;i++){
memset(s,0,sizeof s);
head = tail = 1;
f[i][1] = 0;
s[1] = 1;
for(j = 2;j <= n;j++){
while(s[head] < j - k[i] && head < tail)
head++;
f[i][j] = f[i][s[head]];
if (h[j] >= h[s[head]])
f[i][j]++;
while((f[i][j]<f[i][s[tail]]||(f[i][j]==f[i][s[tail]]&&h[j]>h[s[tail]]))&&head<tail)
tail--;
s[++tail] = j;
}
printf(\"%d\\n\",f[i][n]);
}
继续阅读与本文标签相同的文章
上一篇 :
移动APP反外挂攻防实战
-
裂变方案:三大驱动力让用户主动分享裂变
2026-05-19栏目: 教程
-
华为鸿蒙成第五大操作系统,有希望超过iOS吗?
2026-05-19栏目: 教程
-
先破产再回国 贾跃亭这条路行不通
2026-05-19栏目: 教程
-
圆通速递决战双十一:率先实行涨价策略,其实取胜的关键不在于此
2026-05-19栏目: 教程
-
为什么要拥有一个区块链节点?
2026-05-19栏目: 教程
