优化
最近对于一些动态规划问题有了初步的了解,但是在做题时面临着一系列优化问题,比如最小回文串添加数问题,如果搞不好会出现Memory Limit Exceeded(内存超出,即在出结果之前调用的内存超出了限制)。对于这类问题要回到Dp的本质问题方面进行考虑。Dp的目的是对一个问题进行分解之后对其子问题进行处理的算法,而处理的时候遵循枚举法(听课之前认为是递推)把所有的情况枚举出来然后存储在一个数组里方便调用。而一般的Dp调用的只是与当前数据有关的前几个数据,一般是两个,比如01背包问题、最长公共子序列、求局部最大和问题等等,不过问题是当处理数据过大时,可能定义的数组维数会影响到数据的计算,也就是内存超出问题,所以对于数据过大的问题,有对应的优化方法。
最小回文串添加数:对于任意的字符串数组都可以进行添加字符操作使其变为回文串,题目要求是求解出变为回文串添加字符的最小代价,输入数据有两个N和str,其中N表示字符串的长度,3<=N<=5000,str为数字和大小写字母的混合字符串,输出为变为回文串的最小代价。
由于数据过大定义data[5001][5001]存储计算过的数据显然会出现超出内存问题,采用滚动数组的方法进行优化,源代码如下:
#include<iostream>
#include<cstring>
using namespace std;
int data[2][5003];
int pl(char a[],char b[],int n)
{
int i,j,k,maxi=0;
for(i=0;i<=n;i++)
{data[0][i]=0;data[1][i]=0;}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(a[i-1]==b[j-1])data[i%2][j]=data[(i-1)%2][j-1]+1;
else data[i%2][j]=max(data[i%2][j-1],data[(i-1)%2][j]);/*由于处理的数据至于钱两个数据有关,所以第一维只用两个交换使用就可以了,大大减少了内存的使用,但注意的是,时间复杂度不会改变*/
if(maxi<data[i%2][j])maxi=data[i%2][j];
}
return maxi;
}
int main()
{
char a[5003],b[5003];
int i,m,s,t;
cin>>s;
if(s<3||s>5000)return 0;
cin>>a;
for(i=0,m=s-1;i<s;i++)
b[i]=a[m--];
t=s-pl(a,b,s);
cout<<t<<endl;
return 0;
}
浙公网安备 33010602011771号