Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从给定的一组数中求回文序列的个数_C++_Algorithm_Palindrome - Fatal编程技术网

C++ 从给定的一组数中求回文序列的个数

C++ 从给定的一组数中求回文序列的个数,c++,algorithm,palindrome,C++,Algorithm,Palindrome,假设我们得到一组数字,比如20 40 20 60 80 60 它可以分为两个回文序列:204020,和608060。 它也可以分成6个回文序列,每个序列包含一个数字 如何从C++中给定的一组数字中找到最小回文序列的数量? 这不是我的家庭作业。真正的问题。一个简单的方法是首先查看每个O(n3)子序列,并检查它是否是回文。一旦我们知道哪些子序列是回文序列,我们就可以在O(n2)时间内进行动态规划,以找到覆盖整个序列的最小数量的连续子序列 对于输入 20 40 20 20 80 60 < /COD>,

假设我们得到一组数字,比如20 40 20 60 80 60 它可以分为两个回文序列:
204020
,和
608060
。 它也可以分成6个回文序列,每个序列包含一个数字

如何从C++中给定的一组数字中找到最小回文序列的数量?


这不是我的家庭作业。真正的问题。

一个简单的方法是首先查看每个O(n3)子序列,并检查它是否是回文。一旦我们知道哪些子序列是回文序列,我们就可以在O(n2)时间内进行动态规划,以找到覆盖整个序列的最小数量的连续子序列

对于输入<代码> 20 40 20 20 80 60 < /COD>,C++实现以下打印<代码> [20 40 20 ] [60 80 60 ] < /代码> .<

#include <cstdio>
#include <vector>
using namespace std;

int main() {
  // Read the data from standard input.
  vector<int> data;
  int x;
  while (scanf("%d", &x) != EOF) {
    data.push_back(x);
  }
  int n = data.size();

  // Look at every subsequence and determine if it's a palindrome.
  vector<vector<bool> > is_palindrome(n);
  for (int i = 0; i < n; ++i) {
    is_palindrome[i] = vector<bool>(n);
    for (int j = i; j < n; ++j) {
      bool okay = true;
      for (int left = i, right = j; left < right; ++left, --right) {
        if (data[left] != data[right]) { 
          okay = false;
          break; 
        }
      }
      is_palindrome[i][j] = okay;
    }
  }

  // Dynamic programming to find the minimal number of subsequences.
  vector<pair<int,int> > best(n);
  for (int i = 0; i < n; ++i) {
    // Check for the easy case consisting of one subsequence.
    if (is_palindrome[0][i]) {
      best[i] = make_pair(1, -1);
      continue;
    }
    // Otherwise, make an initial guess from the last computed value.
    best[i] = make_pair(best[i-1].first + 1, i-1);
    // Look at earlier values to see if we can improve our guess.
    for (int j = i-2; j >= 0; --j) {
      if (is_palindrome[j+1][i]) {
        if (best[j].first + 1 < best[i].first) {
          best[i].first = best[j].first + 1;
          best[i].second = j;
        }
      }
    }
  }

  printf("Minimal partition: %d sequences\n", best[n-1].first);
  vector<int> indices;
  int pos = n-1;
  while (pos >= 0) {
    indices.push_back(pos);
    pos = best[pos].second;
  }
  pos = 0;
  while (!indices.empty()) {
    printf("[%d", data[pos]);
    for (int i = pos+1; i <= indices.back(); ++i) {
      printf(" %d", data[i]);
    }
    printf("] ");
    pos = indices.back()+1;
    indices.pop_back();
  }
  printf("\n");

  return 0;
}
#包括
#包括
使用名称空间std;
int main(){
//从标准输入读取数据。
矢量数据;
int x;
while(scanf(“%d”,&x)!=EOF){
数据。推回(x);
}
int n=data.size();
//查看每个子序列并确定它是否是回文。
向量为_回文(n);
对于(int i=0;i=0;--j){
if(是回文[j+1][i]){
if(最佳[j].first+1<最佳[i].first){
最佳[i]。第一=最佳[j]。第一+1;
最佳[i]。第二个=j;
}
}
}
}
printf(“最小分区:%d个序列\n”,最佳[n-1]。第一);
向量指数;
int pos=n-1;
而(位置>=0){
指数。推回(pos);
pos=最佳[pos]。第二;
}
pos=0;
而(!index.empty()){
printf(“[%d”,数据[pos]);

对于(int i=pos+1;i一种简单的方法是首先查看每个O(n3)子序列并检查它是否是回文序列。一旦我们知道哪些子序列是回文序列,我们就可以在O(n2)时间内进行动态规划,以找到覆盖整个序列的最小数量的连续子序列

对于输入<代码> 20 40 20 20 80 60 < /COD>,C++实现以下打印<代码> [20 40 20 ] [60 80 60 ] < /代码> .<

#include <cstdio>
#include <vector>
using namespace std;

int main() {
  // Read the data from standard input.
  vector<int> data;
  int x;
  while (scanf("%d", &x) != EOF) {
    data.push_back(x);
  }
  int n = data.size();

  // Look at every subsequence and determine if it's a palindrome.
  vector<vector<bool> > is_palindrome(n);
  for (int i = 0; i < n; ++i) {
    is_palindrome[i] = vector<bool>(n);
    for (int j = i; j < n; ++j) {
      bool okay = true;
      for (int left = i, right = j; left < right; ++left, --right) {
        if (data[left] != data[right]) { 
          okay = false;
          break; 
        }
      }
      is_palindrome[i][j] = okay;
    }
  }

  // Dynamic programming to find the minimal number of subsequences.
  vector<pair<int,int> > best(n);
  for (int i = 0; i < n; ++i) {
    // Check for the easy case consisting of one subsequence.
    if (is_palindrome[0][i]) {
      best[i] = make_pair(1, -1);
      continue;
    }
    // Otherwise, make an initial guess from the last computed value.
    best[i] = make_pair(best[i-1].first + 1, i-1);
    // Look at earlier values to see if we can improve our guess.
    for (int j = i-2; j >= 0; --j) {
      if (is_palindrome[j+1][i]) {
        if (best[j].first + 1 < best[i].first) {
          best[i].first = best[j].first + 1;
          best[i].second = j;
        }
      }
    }
  }

  printf("Minimal partition: %d sequences\n", best[n-1].first);
  vector<int> indices;
  int pos = n-1;
  while (pos >= 0) {
    indices.push_back(pos);
    pos = best[pos].second;
  }
  pos = 0;
  while (!indices.empty()) {
    printf("[%d", data[pos]);
    for (int i = pos+1; i <= indices.back(); ++i) {
      printf(" %d", data[i]);
    }
    printf("] ");
    pos = indices.back()+1;
    indices.pop_back();
  }
  printf("\n");

  return 0;
}
#包括
#包括
使用名称空间std;
int main(){
//从标准输入读取数据。
矢量数据;
int x;
while(scanf(“%d”,&x)!=EOF){
数据。推回(x);
}
int n=data.size();
//查看每个子序列并确定它是否是回文。
向量为_回文(n);
对于(int i=0;i=0;--j){
if(是回文[j+1][i]){
if(最佳[j].first+1<最佳[i].first){
最佳[i]。第一=最佳[j]。第一+1;
最佳[i]。第二个=j;
}
}
}
}
printf(“最小分区:%d个序列\n”,最佳[n-1]。第一);
向量指数;
int pos=n-1;
而(位置>=0){
指数。推回(pos);
pos=最佳[pos]。第二;
}
pos=0;
而(!index.empty()){
printf(“[%d”,数据[pos]);

对于(int i=pos+1;我请告诉我们你做了什么,至少是你头脑中的一些想法。@aga_pan我想找到一个特定数字的重复次数,并找到所有可能的回文。但现在我不知道该怎么做。@yash.cr7:在你上面给出的示例中,你键入的
20 40 80
正确吗是不是应该是
20 40 20 60 80 60
?我想知道你是在寻找严格连续的子序列,还是也允许非连续的子序列。@MichaelLaszlo对不起,我错了。我编辑了我的问题。它们应该是连续的。非常好,谢谢。你现在有足够的声誉来支持upvot顺便说一句,e答案。请告诉我们你做了什么,至少你脑子里有一些想法。@aga_pan我想找到一个特定数字的重复次数并找到所有可能的回文。但现在我不知道怎么做。@yash.cr7:在你上面给出的例子中,你键入的
20 40 80
正确吗,还是应该是
2040608060
?我想知道你是在寻找严格连续的子序列,还是也允许非连续的子序列。@MichaelLaszlo对不起,我错了。我编辑了我的问题。它们应该是连续的。非常好,谢谢。你现在已经有足够的声誉来支持你了顺便说一句,我认为这不是答案