洛谷 P3102 [USACO14FEB]秘密代码Secret Code 【区间dp】
2017-10-26 13:25
591 查看
农民约翰收到一条的消息,记该消息为长度至少为2,只由大写字母组成的字符串S,他通过一系列操作对S进行加密。
他的操作为,删除S的前面或者后面的若干个字符(但不删光整个S),并将剩下的部分连接到原字符串S的前面或者后面。如对于S=‘ABC’,共有8总可能的操作结果:
AABC
ABABC
BCABC
CABC
4000
ABCA
ABCAB
ABCBC
ABCC
给出加密后的目标字符串,请计算共有多少种加密的方案。
对于同字符的字符串,加密方案不止一种,比如把AA加密成AAA,共有4种加密方案。将你的答案mod 2014后输出。
输入格式:
Line 1: A single encrypted string of length at most 100.
输出格式:
Line 1: The number of ways FJ could have produced this string with one or more successive operations applied to some initial string of length at least 2, written out modulo 2014. If there are no such ways, output zero.
输入样例#1: 复制
输出样例#1: 复制
Here are the different ways FJ could have produced ABABA:
观察题目我们发现一个新的字符串由两部分组成,一部分是原字符串,另一部分是原字符串的前缀或后缀
我们就枚举断点k更新方案数
初始化:
除了f[1][len]外,都设为1,因为每个子串自身就可能成为一种方案,作为转移的基底
状态转移:
对于断点k,分为了[i,k],[k + 1,j]两段,由题另一部分不能与原串相等,故两段长度不能相等,而且长的那一段就一定是原串,若能判定出另一段是该段的前缀或后缀,就可以统计f[i][j] += f[i][k] 或 f[k + 1][j]
判定相等:
串的长度只有100,我们可以开一个macth[i][j][k]表示[i,i + k - 1]与[j,j + k - 1]是否相等,暴力预处理就好了
他的操作为,删除S的前面或者后面的若干个字符(但不删光整个S),并将剩下的部分连接到原字符串S的前面或者后面。如对于S=‘ABC’,共有8总可能的操作结果:
AABC
ABABC
BCABC
CABC
4000
ABCA
ABCAB
ABCBC
ABCC
给出加密后的目标字符串,请计算共有多少种加密的方案。
对于同字符的字符串,加密方案不止一种,比如把AA加密成AAA,共有4种加密方案。将你的答案mod 2014后输出。
输入输出格式
输入格式:Line 1: A single encrypted string of length at most 100.
输出格式:
Line 1: The number of ways FJ could have produced this string with one or more successive operations applied to some initial string of length at least 2, written out modulo 2014. If there are no such ways, output zero.
输入输出样例
输入样例#1: 复制ABABA
输出样例#1: 复制
8
说明
Here are the different ways FJ could have produced ABABA:1. Start with ABA -> AB+ABA 2. Start with ABA -> ABA+BA 3. Start with AB -> AB+A -> AB+ABA 4. Start with AB -> AB+A -> ABA+BA 5. Start with BA -> A+BA -> AB+ABA 6. Start with BA -> A+BA -> ABA+BA 7. Start with ABAB -> ABAB+A 8. Start with BABA -> A+BABA
题解
设f[i][j]为区间[i,j]的方案数观察题目我们发现一个新的字符串由两部分组成,一部分是原字符串,另一部分是原字符串的前缀或后缀
我们就枚举断点k更新方案数
初始化:
除了f[1][len]外,都设为1,因为每个子串自身就可能成为一种方案,作为转移的基底
状态转移:
对于断点k,分为了[i,k],[k + 1,j]两段,由题另一部分不能与原串相等,故两段长度不能相等,而且长的那一段就一定是原串,若能判定出另一段是该段的前缀或后缀,就可以统计f[i][j] += f[i][k] 或 f[k + 1][j]
判定相等:
串的长度只有100,我们可以开一个macth[i][j][k]表示[i,i + k - 1]与[j,j + k - 1]是否相等,暴力预处理就好了
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define LL long long int #define REP(i,n) for (int i = 1; i <= (n); i++) #define fo(i,x,y) for (int i = (x); i <= (y); i++) #define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next) using namespace std; const int maxn = 105,maxm = 100005,INF = 1000000000,P = 2014; inline int read(){ int out = 0,flag = 1;char c = getchar(); while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();} while (c >= 48 && c <= 57) {out = out * 10 + c - 48; c = getchar();} return out * flag; } bool md[maxn][maxn][maxn]; int f[maxn][maxn],len; char s[maxn]; int main() { scanf("%s",s + 1); len = strlen(s + 1); if (len == 2){ cout<<0<<endl; return 0; } REP(i,len) REP(j,len){ for (int k = 1; i + k - 1 <= len && j + k - 1 <= len; k++) if (s[i + k - 1] == s[j + k - 1]) md[i][j][k] = true; else break; } fill(f[0],f[0] + maxn * maxn,1); for (int L = 3; L <=len ; L++) for (int i = 1; i + L - 1 <= len; i++){ int j = i + L - 1; for (int k = i; k < j; k++){ int len1 = k - i + 1,len2 = j - k; if (len1 < len2 && md[i][k + 1][len1]) f[i][j] = (f[i][j] + f[k + 1][j]) % P; if (len1 < len2 && md[i][j - len1 + 1][len1]) f[i][j] = (f[i][j] + f[k + 1][j]) % P; if (len1 > len2 && md[i][k + 1][len2]) f[i][j] = (f[i][j] + f[i][k]) % P; if (len1 > len2 && md[k - len2 + 1][k + 1][len2]) f[i][j] = (f[i][j] + f[i][k]) % P; } } cout<<f[1][len] - 1<<endl; return 0; }
相关文章推荐
- 洛谷 P3102 [USACO14FEB]秘密代码Secret Code 【区间dp】
- P3102 [USACO14FEB]秘密代码Secret Code
- 【USACO14FEB】洛谷3102 Secret Code
- 【USACO14FEB】洛谷2237 Auto-complete
- |BZOJ 1652|区间DP|[Usaco2006 Feb]Treats for the Cows
- bzoj 1652: [Usaco2006 Feb]Treats for the Cows【区间dp】
- 【DP】+【贪心】【前缀和】洛谷P2893 [USACO08FEB]修路Making the Grade 题解
- 【USACO14FEB】洛谷2176 Roadblock
- 洛谷 P2176 [USACO14FEB]路障Roadblock
- 洛谷—— P2176 [USACO14FEB]路障Roadblock
- 1652: [Usaco2006 Feb]Treats for the Cows (区间DP)
- 【bzoj3939】[Usaco2015 Feb]Cow Hopscotch 动态开点线段树优化dp
- 【bzoj1593】[Usaco2008 Feb]Hotel 旅馆 线段树区间合并
- 洛谷 1063 dp 区间dp
- 【bzoj1611】【Usaco2008 Feb】Meteor Shower流星雨 (bfs)题解&代码
- 【bzoj1609】[Usaco2008 Feb]Eating Together麻烦的聚餐 dp
- 【洛谷2982】[Usaco2010 Feb]慢下来Slowdown(dfs序+线段树)
- bzoj 3398 [Usaco2009 Feb]Bullcow 牡牛和牝牛 (dp+前缀)
- [luoguP3146] [USACO16OPEN]248(区间DP)
- BZOJ 1694 & 1742 [Usaco 2005 nov] 区间DP 解题报告