666A-Reberland Linguistics(动态规划)

题目链接:

http://www.codeforces.com/problemset/problem/666/A

题目大意:

给一个单词,分为前缀和后缀两部分,前缀长度不得小于5,后缀长度只能2或3,请输出后缀的个数和所有的后缀,要求所有后缀均不重复。

分析:

其实这道题没有太多的需要人类智慧的算法(我也不会),直接上DP基本都能过。一开始想当然的穷举,结果喜闻乐见的瞬间爆炸了…

DP之前注意要加一个vis数组记录开始位置和长度,防止重复计算属于前缀里的词。代码中用set存储答案纯属个人喜好,也可以用数组之类的代替,应该没太大区别…(我没试过,错了后果自负)。复杂度也不太会算,提交返回46ms似乎挺快,如有大神会算复杂度,欢迎在下面评论。(对,这个博主就是啥都不会还出来浪…)

代码:(渣渣代码,如有雷同,那就雷同呗)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<string>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<vector>
 8 #include<map>
 9 #include<stack>
10 #include<set>
11 #include<cstdlib>
12 #include<deque>
13 #include<queue>
14 #include<bitset>
15 #include<functional>
16 #include<utility>
17 #include<list>
18 #include<iomanip>
19 #include<ctime>
20 #include<cassert>
21 using namespace std;
22
23 char str[10024];
24 bool vis[10024][4];
25 set<string> ans;
26 set<string>::iterator it;
27
28 int main()
29 {
30     int len,sum=0;
31     scanf("%s",str);
32     len=strlen(str);
33     memset(vis,true,sizeof(vis));
34     vis[len][0]=false;
35     for(int i=len;i>=5;i--)
36     {
37         for(int j=0;j<4;j++)
38         {
39
40             if(!vis[i][j])
41             {
42                 string x="",y="";
43                 for(int k=0;k<j;k++)
44                     y=y+str[i+k];
45                 for(int k=1;(i-k)>=5&&k<4;k++)
46                 {
47                     x=str[i-k]+x;
48                     if(x!=y&&k>1)
49                     {
50                         ans.insert(x);
51                         vis[i-k][k]=false;
52                     }
53                 }
54             }
55         }
56     }
57     printf("%d\n",int(ans.size()));
58     for(it=ans.begin();it!=ans.end();it++)
59     {
60         cout<<*it<<endl;
61     }
62     return 0;
63 }
时间: 2024-10-12 14:14:09

666A-Reberland Linguistics(动态规划)的相关文章

[2016-05-04][codeforces][666A - Reberland Linguistics]

时间:2016-05-04 16:51:34 星期三 题目编号:[2016-05-04][codeforces][666A - Reberland Linguistics] 题目大意:一个单词由长度不少于5的词根和长度为2或3的若干个后缀组成,并且两个相邻的后缀不能一样,给定一个单词,问这个单词总共可以有多少个后缀 分析: 类似dp 的思想,dp[i] 表示第i个位置到字符串结束能否划分成合法后缀, 那么dp[i] = dp[i +t] ∧ ( dp[i + 5] ∨ 子串(i,t) != 子串

Codeforces Round #349 (Div. 2) C. Reberland Linguistics DP+set

C. Reberland Linguistics First-rate specialists graduate from Berland State Institute of Peace and Friendship. You are one of the most talented students in this university. The education is not easy because you need to have fundamental knowledge in d

CodeForces 667C Reberland Linguistics

#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include&

Codeforces Round #349 (Div. 2) C. Reberland Linguistics 【DP】

/* *********************************************** Author :Maltub Email :[email protected] Blog :htttp://www.xiang578.com ************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #inclu

codeforces 的20道C题

A - Warrior and Archer CodeForces - 595C n  偶数  然后n个数字 A B 轮流取一个 A让差变小B让差变大 直到最后2 个   求的是最小剩下的差 最后剩下的 L R  相距 n/2    求一下最小的就行 #include <iostream> #include <cstdio> #include <cmath> #include <map> #include <algorithm> #include

Codeforces Round #349 (Div. 2)

终于又回到熟悉的Round了 数学 A - Pouring Rain 设个未知数,解方程,还好没有hack点 #include <bits/stdc++.h> typedef long long ll; const int N = 1e5 + 5; const double PI = acos (-1.0); int main() { double d, h, v, e; scanf ("%lf%lf%lf%lf", &d, &h, &v, &

Leetcode 494 Target Sum 动态规划 背包+滚动数据

这是一道水题,作为没有货的水货楼主如是说. 题意:已知一个数组nums {a1,a2,a3,.....,an}(其中0<ai <=1000(1<=k<=n, n<=20))和一个数S c1a1c2a2c3a3......cnan = S, 其中ci(1<=i<=n)可以在加号和减号之中任选. 求有多少种{c1,c2,c3,...,cn}的排列能使上述等式成立. 例如: 输入:nums is [1, 1, 1, 1, 1], S is 3. 输出 : 5符合要求5种

活动选择的贪心算法与动态规划(未完成)

// greedy_algorithm.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include<queue> using namespace std; #define NofActivity 11 int c[NofActivity + 1][NofActivity + 1]; int reme[NofActivity + 1][NofActivity + 1]; //活动的

求不相邻金币相加和的最大值--动态规划1

求不相邻金币相加和的最大值. 输入n个金币的金币面值(正数自定义),求这些金币不相邻和的最大值. 动态规划问题1 设f(n)为第n个金币数的最大值,f(0)=0,f(1)=a[1],输入的数组从下标为1开始. f(n)=max{a[n]+f(n-2),f(n-1)}. 代码如下: import java.util.Scanner; public class Jin_bi_zui_da_zhi { public static void main(String[] args) { Scanner s