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 }
posted @ 2014-12-14 15:44  Naturain  阅读(102)  评论(0编辑  收藏  举报