CF #282 div1
2014-12-14 11:52:51
总结:--不说了,FST爆零滚粗.....下场老老实实打div2
A:简单贪心....手贱写的不够暴力。。。(果然cf这种题一定要暴力!)贪心策略就是除了最后一个#,前面都放一个')',最后一个#放多个
1 /************************************************************************* 2 > File Name: a.cpp 3 > Author: Natureal 4 > Mail: 564374850@qq.com 5 > Created Time: Sun 14 Dec 2014 12:29:13 AM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 typedef unsigned long long ull; 26 const int INF = 1 << 30; 27 28 char s[100010]; 29 int len; 30 int ans[100010]; 31 32 int main(){ 33 scanf("%s",s); 34 len = strlen(s); 35 int cnt1 = 0,cnt2 = 0,flag = 1,p; 36 for(int i = 0; i < len; ++i){ 37 if(s[i] == '(') 38 cnt1++; 39 else if(s[i] == ')') 40 cnt2++; 41 else{ 42 cnt2++; 43 ans[i] = 1; 44 p = i; 45 } 46 if(cnt2 > cnt1){ 47 flag = 0; 48 break; 49 } 50 } 51 if(flag == 0) printf("-1\n"); 52 else{ 53 ans[p] += cnt1 - cnt2; 54 cnt1 = cnt2 = 0; 55 for(int i = 0; i < len; ++i){ 56 if(s[i] == '(') ++cnt1; 57 else if(s[i] == ')') ++cnt2; 58 else cnt2 += ans[i]; 59 if(cnt2 > cnt1){ 60 flag = 0; 61 break; 62 } 63 } 64 if(flag == 0){ 65 printf("-1\n"); 66 return 0; 67 } 68 for(int i = 0; i < len; ++i){ 69 if(s[i] == '#') printf("%d\n",ans[i]); 70 } 71 } 72 return 0; 73 }
B:KMP+DP
嘛...比赛时知道用KMP求个匹配点....但死活想不到DP思路....深深感觉到自己平时刷的题目是在是水。。就会个KMP裸题--,转战bzoj算了。。。
思路:先用KMP预处理处t的每个匹配终点。
dp[i]表示前i个字符的解(即:s0,s1,....,si-1)然后我们逐渐拓展i,并且计算每一个i:
(1)dp[i] = dp[i - 1] //首先i继承自i-1,含义:不取第i个字符
开一个last变量来记录当前i个字符中最后一个匹配t的起点。
(2)如果之前已经出现过匹配t的情况,那么last就有值:
dp[i] += last +1 //如果我们先取 last ~ i 这一串,然后向左边拓展,由于该串已经包含了一个t,那么向左边拓展时肯定也合法,有last+1种(此时我们只算k=1的情况)
(3)dp[i] += sum[last - 1] //如果我们取last ~ i 这一串,然后另外的串由前last-1个字符决定,那么就要加上sum[last - 1]表示前面的所有解。
1 /************************************************************************* 2 > File Name: b.cpp 3 > Author: Natureal 4 > Mail: 564374850@qq.com 5 > Created Time: Sun 14 Dec 2014 12:45:18 AM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 typedef unsigned long long ull; 26 const int INF = 1 << 30; 27 const int maxn = 100010; 28 const ll Mod = 1e9 + 7; 29 30 int P[maxn],len1,len2; 31 char t[maxn],s[maxn]; 32 int g[maxn]; 33 ll dp[maxn],sum[maxn]; 34 35 void Get_P(){ 36 P[0] = -1; 37 int j = -1; 38 for(int i = 1; i < len2; ++i){ 39 while(j > -1 && t[j + 1] != t[i]) j = P[j]; 40 if(t[j + 1] == t[i]) j++; 41 P[i] = j; 42 } 43 } 44 45 void KMP(){ 46 int j = -1; 47 for(int i = 0; i < len1; ++i){ 48 while(j > -1 && t[j + 1] != s[i]) j = P[j]; 49 if(t[j + 1] == s[i]) j++; 50 if(j == len2 - 1) j = P[j],g[i] = 1; 51 } 52 } 53 54 int main(){ 55 scanf("%s%s",s,t); 56 len1 = strlen(s); 57 len2 = strlen(t); 58 Get_P(),KMP(); 59 ll last = -1; 60 for(int i = 0; i < len1; ++i){ 61 if(i) dp[i] = dp[i - 1]; 62 if(g[i] == 1) last = i - len2 + 1; 63 if(last != -1) dp[i] += (last > 0 ? sum[last - 1] : 0) + last + 1; 64 sum[i] = (i > 0 ? sum[i - 1] : 0) + dp[i]; 65 dp[i] %= Mod,sum[i] %= Mod; 66 } 67 printf("%I64d\n",dp[len1 - 1]); 68 return 0; 69 }