1 条题解

  • 0
    @ 2025-8-24 22:30:05

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar yz_zy
    **

    搬运于2025-08-24 22:30:05,当前版本为作者最后更新于2025-04-26 15:56:25,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    P7458 [CERC2018] Clockwork ||ange

    此题可考虑 dpdp.

    dp[i][j]dp[i][j] 表示的状态是第 ii 次跳跃跳了 jj 步后的最佳畜栏轮廓。

    例如:

    初状态为 1001010010

    dp[1][1]=11011=27dp[1][1]=11011=27dp[1][2]=10110=22dp[1][2]=10110=22dp[2][1]=11111=31dp[2][1]=11111=31

    显然就有 dp[i1][k]dp[i][j]dp[i-1][k] \to dp[i][j],其中

    dp[i][j]=(dp[i1][k]>>j)    dp[i1][k]dp[i][j]=(dp[i-1][k]>>j)\; \| \; dp[i-1][k]

    但是有一个问题,dp[i][j]dp[i][j] 可以从多个状态转移过来,那么这些状态之间应该如何做取舍呢?

    我们可以猜测出来,这应该是取最值,即:

    $$dp[i][j]=max((dp[i-1][k]>>j)\; \| \; dp[i-1][k]\; ,\;dp[i][j]) $$

    证明:

    设有两串二进制数 a,ba,ba>ba>b

    那么可分为 33 种情况:

    1. aa11 的数量要多于 bb 中的 11 的数量,显然要选择 aa

    2. aa11 的数量与 bb11 的数量相等,因为 a>ba>b ,所以 aa 中的 11 都在高位上,这些 11 都可以往低位走,它的潜力更大,故选择 aa

    3. aa11 的数量小于 bb11 的数量,bb 中的 11 全部堆积在低位上,高位的很难顾及到,故选择 aa

    证毕。

    这么做下来竟然可以拿到最优解!

    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
    上传者