开始老是往贪心or模拟方面想,但是后效性很明显啊!!

话说为什么每次codeforce上的dp我都不会哎~

定 义 d p [ i ] [ 0 / 1 ] 表 示 以 i 开 头 连 续 2 / 3 个 字 母 一 组 , 后 面 的 字 母 有 合 法 分 组 方 式 定义dp[i][0/1]表示以i开头连续2/3个字母一组,后面的字母有合法分组方式 dp[i][0/1]i2/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; 
}