【问题标题】:Is there a way to optimize space in this DP program?有没有办法优化这个 DP 程序中的空间?
【发布时间】:2016-04-10 07:24:13
【问题描述】:

问题陈述:

回文是一个对称的字符串,即从左到右以及从右到左读取相同的字符串。你要编写一个程序,给定一个字符串,确定要插入字符串中的最少字符数,以获得回文。例如,通过插入 2 个字符,字符串“Ab3bd”可以转换为回文(“dAb3bAd”或“Adb3bdA”)。但是,插入少于 2 个字符不会产生回文。

输入

第一行包含一个整数:输入字符串的长度N,3≤N≤5000。第二行包含一个长度为 N 的字符串。该字符串由从“A”到“Z”的大写字母、从“a”到“z”的小写字母和从“0”到“9”的数字组成。大写和小写字母被认为是不同的。

输出

第一行包含一个整数,这是所需的最小数字。

问题链接 => http://www.spoj.com/problems/IOIPALIN/

我的解决方案:

#include <iostream>
#include <memory.h>
#include <cstdio>
using namespace std;

long  memo[5010][5010];
string s;
 long int n;
long  solve(long  i,long  j){

if(memo[i][j]!=-1){
return memo[i][j];
}
if(i>=j)
 return 0;
 if(s[i]==s[j])
   return solve(i+1,j-1);
 return memo[i][j]= min(solve(i,j-1)+1,solve(i+1,j)+1);
}

int  main()
{
ios_base::sync_with_stdio(false);
long int  n ;
cin>>n;
cin>>s;
memset(memo,-1,sizeof(memo));

long int a = solve(0,n-1);
cout << a << endl;
return 0;
}

我收到此代码的“超出时间限制”。我怎样才能解决这个问题 ?

【问题讨论】:

  • 请注意,“DP程序”是多余的。

标签: c++ dynamic-programming memoization


【解决方案1】:

作为一名程序员,直接询问问题的解决方案是一种不好的做法。具体代码我不会给你,但是我会帮你解决问题的。

要解决这个问题,需要 n^2 方法。动态编程是您所需要的。为此,请创建一个与str 相反的字符串rev_str。现在看下面的伪代码。

for(i = 0 to n) 
    for(j = 0 to n)
       if(i = 0 or j = 0) dp[j][1] = 0;
       else if(str[i - 1] = rev_str[j - 1]) dp[j][1] = dp[j - 1][0] + 1;
       else dp[j][1] = max(dp[j][0], dp[j - 1][1];
    for (j = 0 to n) dp[j][0] = dp[j][1];

您的答案将是n - dp[n][0]

基本上,我们要做的是在每一步中找到从strrev_str 匹配的最大字符数。其余的将需要添加。从而给出答案。

【讨论】:

  • 我的解决方案的复杂性也是 O(n^2) 。不是吗?
  • min(solve(i,j-1)+1,solve(i+1,j)+1); 语句中,您正在创建两个分支并解决它们。所以在最坏的情况下,如果每次都执行这个语句,你的执行就会加倍,从而复杂度为 O(2^n)。
  • 但是我用过 memoization 。它不会降低时间复杂度吗?
  • 是的,抱歉,我没看到。
  • 好吧,也许它给了你 TLE,因为在使用备忘录时,它的值大多数时候是 -1,这意味着你实际上并没有使用它的值。请尝试试运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多