C++程序:查找移除回文子列表所需的运算次数
假设我们有一个称为nums的数字列表。现在让我们考虑一个操作,其中我们删除一些作为回文的子列表。我们必须找到使列表为空所需的最小操作次数。
因此,如果输入类似于nums = [6, 2, 4, 4, 2, 10, 6],则输出将为2,因为我们可以先删除子列表[2, 4, 4, 2],然后列表变为[6, 10, 6],这也是一个回文,因此将其删除以使列表为空。
为了解决这个问题,我们将遵循以下步骤:
定义一个大小为105 x 105的数组dp。
定义一个函数dfs(),它将接收i、j和一个数组v作为参数。
ret := inf
如果i > j,则:
返回0
如果i与j相同,则:
返回1
如果j - i与1相同,则:
返回(如果v[i]与v[j]相同,则返回1,否则返回2)
如果i + 1 <= j且v[i]与v[i + 1]相同,则:
ret := 1 + dfs(i + 2, j, v)
如果dp[i, j]不等于-1,则:
返回dp[i, j]
ret := (ret, 1 + (dfs(i + 1, j, v)和dfs(i, j - 1, v)的最小值))的最小值
如果v[i]与v[j]相同,则:
ret := ret和dfs(i + 1, j - 1, v)的最小值
初始化k := i + 2,当k < j时,更新(增加k的值),执行:
如果v[i]与v[k]相同,则:
ret := ret和dfs((i + 1, k - 1, v) + dfs(k + 1, j, v))的最小值
返回dp[i, j] = ret
从主方法执行以下操作:
用-1填充dp
n := nums的大小
返回dfs(0, n - 1, nums)
示例
让我们查看以下实现以获得更好的理解:
#include <bits/stdc++.h>
using namespace std;
int dp[105][105];
int dfs(int i,int j, vector <int>& v){
int ret= INT_MAX;
if(i > j)
return 0;
if(i == j)
return 1;
if(j - i == 1){
return v[i] == v[j] ? 1 : 2;
}
if(i + 1 <= j && v[i] == v[i + 1]){
ret = 1 + dfs(i + 2, j, v);
}
if(dp[i][j] != -1) return dp[i][j];
ret = min({ret, 1 + min(dfs(i + 1, j, v), dfs(i, j - 1, v))});
if(v[i] == v[j]){
ret = min(ret, dfs(i + 1, j - 1, v));
}
for(int k = i + 2; k < j; k++){
if(v[i] == v[k]){
ret = min(ret, dfs(i + 1, k - 1, v) + dfs(k + 1, j, v));
}
}
return dp[i][j] = ret;
}
int solve(vector<int>& nums) {
memset(dp , -1, sizeof dp);
int n = nums.size();
return dfs(0, n - 1, nums);
}
int main(){
vector<int> v = {6, 2, 4, 4, 2, 10, 6};
cout << solve(v);
}输入
{6, 2, 4, 4, 2, 10, 6}输出
2
广告
数据结构
网络
关系型数据库管理系统
操作系统
Java
iOS
HTML
CSS
Android
Python
C语言编程
C++
C#
MongoDB
MySQL
Javascript
PHP