开始老是往贪心or模拟方面想,但是后效性很明显啊!!
话说为什么每次codeforce上的dp我都不会哎~
定 义 d p [ i ] [ 0 / 1 ] 表 示 以 i 开 头 连 续 2 / 3 个 字 母 一 组 , 后 面 的 字 母 有 合 法 分 组 方 式 定义dp[i][0/1]表示以i开头连续2/3个字母一组,后面的字母有合法分组方式 定义dp[i][0/1]表示以i开头连续2/3个字母一组,后面的字母有合法分组方式
那 么 转 移 非 常 明 显 , 觉 得 不 明 显 就 看 代 码 把 那么转移非常明显,觉得不明显就看代码把 那么转移非常明显,觉得不明显就看代码把
最 后 用 一 个 s e t 去 重 最后用一个set去重 最后用一个set去重
//定义dp[i][0/1]表示以i开头的长度2(3)的子串能否满足
#include <bits/stdc++.h>
using namespace std;
int dp[10009][3];
char a[10009];
set<string>s;
int main()
{
cin >> (a+1);
int len=strlen(a+1);
dp[len+1][0]=dp[len+1][1]=1;
for(int i=len-1;i>=6;i--)
{
if( a[i]!=a[i+2] || a[i+1]!=a[i+3] )
dp[i][0]|=dp[i+2][0];
dp[i][0]|=dp[i+2][1];//前面是2后面是3
if( a[i]!=a[i+3] || a[i+1]!=a[i+4] || a[i+2]!=a[i+5] )
dp[i][1]|=dp[i+3][1];
dp[i][1]|=dp[i+3][0];//前面是3后面是2
}
for(int i=6;i<=len-1;i++)
{
string w="";
w+=a[i]; w+=a[i+1];
if( dp[i][0] ) s.insert( w );
if( dp[i][1] )
{
w+=a[i+2];
s.insert( w );
}
}
cout << s.size() << endl;
set<string>::iterator it=s.begin();
for( ;it!=s.end();it++)
cout << *it << endl;
}