1 条题解
-
0
自动搬运
来自洛谷,原作者为

yz_zy
**搬运于
2025-08-24 22:30:05,当前版本为作者最后更新于2025-04-26 15:56:25,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
P7458 [CERC2018] Clockwork ||ange
此题可考虑 .
设 表示的状态是第 次跳跃跳了 步后的最佳畜栏轮廓。
例如:
初状态为 ,
则 ,,。
显然就有 ,其中
但是有一个问题, 可以从多个状态转移过来,那么这些状态之间应该如何做取舍呢?
我们可以猜测出来,这应该是取最值,即:
$$dp[i][j]=max((dp[i-1][k]>>j)\; \| \; dp[i-1][k]\; ,\;dp[i][j]) $$证明:
设有两串二进制数 且 。
那么可分为 种情况:
-
中 的数量要多于 中的 的数量,显然要选择 。
-
中 的数量与 中 的数量相等,因为 ,所以 中的 都在高位上,这些 都可以往低位走,它的潜力更大,故选择 。
-
中 的数量小于 中 的数量, 中的 全部堆积在低位上,高位的很难顾及到,故选择 。
证毕。
这么做下来竟然可以拿到最优解!
Code
#include<bits/stdc++.h> #define int long long using namespace std; const int N=1e5+5; string s; int f[N][45],n; signed main(){ cin.tie(0);cout.tie(0); ios::sync_with_stdio(false); cin>>s;n=s.size();s=' '+s; int now=0; for(int i=n;i>=1;i--){ now=now+(int)(s[i]-'0')*((int)1<<(n-i)); } for(int i=1;i<=40;i++) f[0][i]=now; for(int i=1;i<=n;i++){ for(int j=1;j<=40;j++){ for(int k=1;k<=40;k++){ f[i][j]=max((f[i-1][k]>>j)|f[i-1][k],f[i][j]); } } } for(int i=0;i<=n;i++){ for(int j=1;j<=40;j++){ if((int)f[i][j]==(int)(((int)1<<n)-1)){ cout<<i; return 0; } } } cout<<-1; return 0; } -
- 1
信息
- ID
- 6620
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者