Code[VS] 3301 Square words
来源:互联网 发布:90年代网络歌曲 编辑:程序博客网 时间:2024/05/17 22:07
【题意】
定义square words为:
1.长度为偶数;
2.前一半等于后一半;
比如abcabc和aaaa都是square words,但是abcabcab和aaaaa都不是。
现在有一个长度为n的字符串,求至少要删掉多少个字符,使得剩下的字符串是square words。
(n ≤ 500)
【构思】
数据范围不大,n^3即可;
前一半=后一半,说明有两部分相同,从某个点断开有子序列相同;
枚举断点,然后变成两个字符串p,q,字符串从前往后匹配,满足无后效性;
设f[i][j]表示把p匹配到第i位,q匹配到第j位的最长子序列的长度;
则f[i][j]=max(f[i-1][j-1]+(p[i]==p[j]),f[i-1][j],f[i][j-1]),
然后结果就取字符串长度-最大的子序列长度。
时间复杂度:O(N^3)
空间复杂度:O(N^2)
【实现】
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int N=510;
int ls,res,f[N][N];
char s[N],p[N],q[N];
int max(int i,int j)
{
return i>j?i:j;
}
int get(int lp,int lq)
{
memset(p,0,sizeof p);
memset(q,0,sizeof q);
memset(f,0,sizeof f);
for (int i=1;i<=lp;i++) p[i]=s[i-1];
for (int i=1;i<=lq;i++) q[i]=s[i+lp-1];
for (int i=1;i<=lp;i++)
for (int j=1;j<=lq;j++) f[i][j]=max(f[i-1][j-1]+(p[i]==q[j]),max(f[i][j-1],f[i-1][j]));
return f[lp][lq];
}
int main(void)
{
scanf("%d%s",&ls,s);
for (int i=0;i<=ls;i++) res=max(res,get(i,ls-i));
printf("%d\n",ls-res*2);
return 0;
}
【回顾】
[1] 转化思想:①字母与数的相互转化 ②树与序列的相互转化 ③环与序列的相互转化
[2] 对于字符串的问题,如最长公共子串,还有DP的方法解决
[3] 无后效性的判定 ①位置的单向变化 ②数字的单调变化 ③树结构 ④下标的单调变化(匹配)
[4] 解决问题:①类比 ②简单-特殊化 ③分析对偶问题(最大-最小问题等)
- Code[VS] 3301 Square words
- code[vs]3301 Square words
- codevs 3301 Square words 题解报告
- ural 1007 Code Words
- ural 1007 Code Words
- URAL 1007 - Code Words
- VS Code
- VS Code
- VS Code
- VS Code
- VS Code
- vs code
- VS Code
- 【code forceB】Non-square Equation
- 【Google Code Jam】Reverse Words
- ural1007 Code Words (字符串处理)
- leetcode 日经贴,Cpp code -Maximal Square
- Software architecture vs code
- Code[VS] 1090 加分二叉树
- C语言指针系列四——指针与函数
- LeetCodeOJ. Linked List Cycle
- ENVI自学笔记一
- Android开发者必须知道的内存管理知识
- Code[VS] 3301 Square words
- Code[VS] 1436 孪生素数2
- Code[VS] 2046 孪生素数3
- 【Codechef】February Challenge 2015 Chef and Strings
- Code[VS] 1481 忠诚
- 编程笔记_JAVA_正则表达式工具
- 编程笔记_JAVA_正则表达式工具
- 怎样利用编程解决问题?
- NOIP 2014 提高组 Day1 T1 生活大爆炸版石头剪刀布