• POJ1159


    这竟然是IOI虽然是2000年的,但其实也改变不了它水题的本质

    我写了两种方法,这里都讲一下吧

    考虑记忆化搜索,用f[i][j]表示当区间的左端为i,右端为j时最少要添加多少字符,所以ans就为f[1][n]

    然后考虑一下,对于每一个f[i][j],都有转移:

    • s[i]==s[j],则有f[i][j]=f[i+1][j-1]

    • s[i]!=s[j] ,则有f[i][j]=min(f[i+1][j],f[i][j-1])(左右两边加一个字符,看看那种情况更优)

    这里连枚举的顺序也懒得推了,直接跑了个记忆化搜索就过了

    CODE

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=5005;
    short int f[N][N],n;
    char s[N];
    inline int min(int a,int b)
    {
    	return a<b?a:b;
    }
    inline void DP(int l,int r)
    {
    	if (l>=r) { f[l][r]=0; return; }
    	if (s[l]==s[r])
    	{
    		if (f[l+1][r-1]==-1) DP(l+1,r-1);
    		f[l][r]=f[l+1][r-1];
    	} else
    	{
    		if (f[l+1][r]==-1) DP(l+1,r);
    		if (f[l][r-1]==-1) DP(l,r-1);
    		f[l][r]=min(f[l+1][r],f[l][r-1])+1;
    	}
    }
    int main()
    {
    	scanf("%d%s",&n,s+1);
    	memset(f,-1,sizeof(f));
    	DP(1,n);
    	printf("%d",f[1][n]);
    	return 0;
    }
    

    注意这里的内存问题,开int的话都是要MLE的,但是由于数据范围5000,因此开short int足矣

    还有一种算法,就是很套路的了

    我们很轻易的发现,将原串倒过来之后,他们的最长公共子序列LCS都是不用再添加字符的,而对于其它的字符每个都要找一个字符与之相对应地匹配

    证明不难,这里省略了,观察即可得出

    LCS的DP方程也很简单,用f[i][j]表示第一个串前i个字符,第二个串前j个字符的LCS是多少,转移有

    • s[i]==s[j] f[i][j]=f[i-1][j-1]+1

    • s[i]!=s[j] f[i][j]=max(f[i-1][j],f[i][j-1])(之前的决策二选一)

    是不是觉得和第一种的DP式有几分相似?其实他们本质上也是一样的!

    所以又可以请出滚存来优化内存了

    CODE

    #include<iostream>
    #include<string>
    using namespace std;
    const int N=5005;
    int f[2][N],n;
    string s1;
    inline int max(int a,int b)
    {
    	return a>b?a:b;
    }
    int main()
    {
    	int i,j;
    	ios::sync_with_stdio(false);
    	cin>>n>>s1; string s2(s1.rbegin(),s1.rend());
    	for (i=0;i<n;++i)
    	{
    		int now=(i+1)&1,lst=now^1;
    		for (j=0;j<n;++j)
    		if (s1[i]==s2[j]) f[now][j+1]=f[lst][j]+1; else f[now][j+1]=max(f[lst][j+1],f[now][j]);
    	}
    	cout<<n-f[n&1][n]<<endl;
    	return 0;
    }
    
  • 相关阅读:
    对象属性操作-包含kvc---ios
    UserDefault的使用,保存小数据到本地-iOS
    单例模式-ios
    值类型和引用类型
    [fn]焦点图JQ插件版
    [f]区间随机数函数
    css3动画特效集合
    js中的事件代理(委托)
    Nodejs入门【转载】保留备用
    canvas打字效果
  • 原文地址:https://www.cnblogs.com/cjjsb/p/9029064.html
Copyright © 2020-2023  润新知