1 条题解

  • 0
    @ 2026-5-5 16:43:25

    题目传送门

    大意

    有一个长度为 nn 的初始值均为 00 的序列 aa,每次操作可以将其中一个子串统一改成任意值。

    现给定一个长度为 nn 的目标序列 arrarr,求最少操作几次可以把 aa 变为 bb

    思路

    一道区间 dp 的模板题。

    我们第一层循环遍历长度 ll,第二层循环遍历开头 ii,就可以算出结尾 jj,第二层循环遍历中间的每一个点 kk

    状态转移方程:

    如果 aiaja_i \ne a_j,那么 dp[i][j]=min(dp[i][k]+dp[k+1][j],dp[i][j])dp[i][j] = \min(dp[i][k]+dp[k+1][j],dp[i][j])

    如果 ai=aja_i = a_j,那么 dp[i][j]=min(dp[i][j1],dp[i1][j])dp[i][j] = \min(dp[i][j-1],dp[i-1][j])


    代码

    #include <bits/stdc++.h>
    using namespace std;
    long long n,dp[305][305],arr[305];
    int main(){
    	ios::sync_with_stdio(0),cin.tie(0);
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>arr[i];
    	}
    	memset(dp,0x3f,sizeof(dp));//初始化
    	for(int i=1;i<=n;i++){
    		dp[i][i]=1;
    	}
    	for(int l=2;l<=n;l++){
    		for(int j=l;j<=n;j++){
    			int i=j-l+1;
    			for(int k=i;k<j;k++){
    				dp[i][j]=min(dp[i][k]+dp[k+1][j],dp[i][j]);
    			}
    			if(arr[i]==arr[j]){
    				dp[i][j]=min(dp[i][j-1],dp[i-1][j]);
    			}
    		}
    	}
    	cout<<dp[1][n];
    	return 0;
    }
    
    • 1

    信息

    ID
    7052
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者