SDUT OJ 2607
2013-08-14 15:07
204 查看
/*http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2607*/ 题目大意:给出一个字符串,求出里面为山字形的子序列,比如1 2 1,给出的字符串都是 小写字母组成,大小按照码值判断,问里面有几个这样的子序列,保证长度大于等三,且中点左右必须至少有一个字符。注意:相同的两个算两个 比如acca算aca和aca两个,其中c的下标分别为1和2。 解法:既然是左边递增右边递减,那么我们左右都求一次递增子序列的个数,然后相乘就是相加就是所有的组合数 因为字母只有26个,那么时间复杂度为O(26*n); 建立一个hash字母表记录到小标i为止前面出现过的以每个字母结尾的递增子序列个数,单个不算 比如:abca,到小标2时枚举hash表的0到1,以前求出的hash[0]=1,hash[1]为2,那么hash[2]=3,虽然单个的不算,但是每次算完dp[i] 的值要加上s[i]这一个单词以保证后面的字母加上s[i]可以得到一个长度大于等于2的子序列 ,然后逆着再做一遍,就可算出正着的和逆序的以每个字母结尾的长度在二和二以上的 #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int dp[100010]; char s[100010]; int hash[30]; int main() { int i,j,n,c; long long sum,ok; while(scanf("%d",&n)!=EOF) { scanf("%s",s); memset(hash,0,sizeof(hash)); for(i=0;i<n;i++) { dp[i]=0; c=s[i]-'a'; for(j=0;j<c;j++) { dp[i]+=hash[j]; dp[i]=dp[i]%2012; } hash[c]+=dp[i]+1;//加1,相当于加上s[i]这个字母 hash[c]=hash[c]%2012; } memset(hash,0,sizeof(hash)); sum=0; for(i=n-1;i>=0;i--) { c=s[i]-'a'; ok=0; for(j=0;j<c;j++) { ok+=hash[j]; ok=ok%2012; } hash[c]+=ok+1; hash[c]=hash[c]%2012; sum=sum+(dp[i]*ok); sum=sum%2012; } printf("%lld\n",sum); } return 0; } /************************************** Problem id : SDUT OJ 2607 User name : ORC Result : Accepted Take Memory : 756K Take Time : 150MS Submit Time : 2013-08-14 14:45:07 **************************************/
相关文章推荐
- poj 2607 Fire Station
- sdutoj-2607-Mountain Subsequences
- sdut OJ2141---图论--用的数组+BFS
- sdut oj 排队买饭
- SDUT OJ 3045 迷之图论 (树的直径)
- SDUT OJ 2399 Palindrome
- SDUT oj 3005 打怪升级(内存搜索)
- POJ 2607 Fire Station 消防站
- SDUT OJ 2129 树结构练习——判断给定森林中有多少棵树
- SDUT OJ 3362 数据结构实验之图论六:村村通公路
- SDUT OJ 3404 数据结构实验之排序七:选课名单
- SDUT OJ 数据结构实验之链表七:单链表中重复元素的删除
- C语言实验——用*号输出字母C的图案 (sdut oj)
- 小鑫の日常系列故事(一)——判断对错 (sdut oj)
- 相似三角形 (sdut oj)
- C语言实验——打印数字图形 (sdut oj)
- C语言实验——一元二次方程Ⅰ (sdut oj)
- C语言实验——数组逆序 (sdut oj)
- 鞍点计算 (sdut oj)
- 简单字符串比较 (sdut oj)