1 条题解

  • 0
    @ 2025-8-24 22:47:31

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar JF
    天真在这条路上 / 跌跌撞撞 / 他被芒草割伤 ||越渴望着实现目标,那赶紧给我行动起来,跟他爆了 ||情为何物,生死相许

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

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

    以下是正文


    注意,所有的 aia_i 都是正数。

    对于第一档分,1010 pts,是给暴力的。

    对于第二档分,可以考虑一个 dpdpdpidp_i 表示 消完 11ii 所要的代价最小,那就从当前的 ii 往前找,找到能消去的(颜色相同)去更新 dpidp_i 的值,方程是:

    dp[i]=min(dp[i],a[i]+a[j]+dp[j1])dp[i]=min(dp[i],a[i]+a[j]+dp[j-1])

    时间是 O(t×n2)O(t\times n^2)

    接下来看正解:

    分两类讨论。

    • c1=cnc_1=c_n

    对于这种情况的话,直接选择 [1,n][1,n] 这个区间消去即可。代价为 a1+ana_1+a_n。这样做是最优的,因为 11nn 两个位置作为首尾,消去的时候这两个位置必选,那么就必然含有 a1a_1ana_n,加上如果中间选择一些辅助 aia_i 进行消去,必然不如第一种消去方法优秀。

    所以我们有结论,对于 l,rl,r,如果 cl=crc_l=c_r,那么消去这个区间的最小代价就一定是 al+ara_l+a_r

    • c1!=cnc_1 !=c_n

    首先有的一个结论是,必然会存在至少一个 cic_ici+1c_{i+1},使得 cic_i 等于 c1c_1cnc_n 等于 ci+1c_{i+1}(1in1)(1\le i \le n-1)

    考虑采用反证法证明,如果不存在的话,c2c_2 必然会等于 c1c_1(如果不等于 c1c_1 的话就符合上面的情况了。)以此类推, cn1=c1c_{n-1}=c_1,但是这样的话 cn=cn,c1=cn1c_n=c_n,c_1=c_{n-1},也就是 [1,n1][1,n-1][n,n][n,n] 两个区间,矛盾。故得证。

    所以我们可以找到至少一组 c1=ci,ci+1=cnc_1=c_i,c_{i+1}=c_n 的情况,根据第一种情况的结论,那么最小值就是 (a1+ai)+(ai+1+an)(a_1+a_i)+(a_{i+1}+a_n)O(n)O(n) 的时间扫一遍找这个值的最小就好。

    时间为 O(t×n)O(t \times n)

    #include<bits/stdc++.h>
    using namespace std;
    const int N =5e6+10;
    #define int long long
    int a[N],c[N];
    signed main()
    {
    	int t;
    	cin>>t;
    	while(t--)
    	{
    		int n;
    		cin>>n;
    		for(int i=1;i<=n;i++)
    			cin>>a[i];
    		for(int i=1;i<=n;i++)
    			cin>>c[i];
    		if(c[1]==c[n])
    		{
    			cout<<a[1]+a[n]<<endl;
    			continue;
    		}
    		int ans=LONG_LONG_MAX;
    		for(int i=1;i<n;i++)
    			if(c[i]==c[1]&&c[i+1]==c[n])
    				ans=min(ans,a[i]+a[1]+a[n]+a[i+1]);
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    
    
    • 1

    信息

    ID
    8230
    时间
    1000ms
    内存
    128MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者