训练一2016.8.30:2016 USP-ICMC(简单难度)(未完成2两题)

  链接:http://acm.hust.edu.cn/vjudge/contest/130818#problem/K

  时长:3h

  总结:题目难度是GYM 3星,3小时6题。前期过题比较慢,两个最水题的用了1个多小时,原因在于:英语比较弱,题意较难理解。

还有kalili的个人原因,就是前期不够劲T T,感觉不在状态,kalili贡献了4道题,3个wa,平均每题用时30分钟,代码速度和正确率有待提高。这也导致了赛后8分钟又过了一题,赛时写完的时候错误太多,没调好。这是值得改进的地方。

 

题解:
A:几何DP(kalili补)

注意到每个环上的点可以只连此环旁边的两个点,这样就可以在环上进行DP,因为是圈,所以要DP两边,让首尾连起来

B: 模拟贪心 (kalili 补)

C: 状压暴力 (kalili done)

D: 后缀数组DP(kalili补)

LCS的变形,因为这里的序列不是数的序列,而是字符串的序列,求最长的公共子字符串序列。

首先还是一样的LCS惯用DP手段,dp[N][N], 还有注意这里的序列是字符串,所以还要加一维当前两个串互相匹配到哪个状态了。

所以是dp[N][N][len][2],不管怎样肯定是可以dp出来的,我写的比较繁琐

另外get到一个短小的后缀数组板子,用的是sort排序,直接倍增求的LCP

 1 typedef vector<int> vi;
 2 struct SA {
 3   const int L; string s; int i, skip, lvl;
 4   vector<vi> P; vector<pair<pii,int> > M;
 5   
 6   SA(const string &s) : L(s.size()), s(s), P(1, vi(L, 0)), M(L) {
 7     for (i = 0; i < L-(L==1); i++) P[0][i] = int(s[i]);
 8     for (skip = 1, lvl = 1; skip < L; skip *= 2, lvl++) {
 9       P.push_back(vi(L, 0));
10       for (int i = 0; i < L; i++)
11         M[i] = make_pair(pii(P[lvl-1][i], i+skip<L ? P[lvl-1][i + skip] : -1000), i);
12       sort(M.begin(), M.end());
13       for (int i = 0; i < L; i++)
14         P[lvl][M[i].second] = (i > 0 && M[i].first == M[i-1].first) ? P[lvl][M[i-1].second] : i; 
15     } 
16   }
17   
18   const vi& get_sa() { return P.back(); }
19   //returns len of longest common prefix of s[i...L-1] and s[j...L-1], O(lg L)
20   int lcp(int i, int j) {
21     int len = 0; if (i == j) return L - i;
22     for (int k = P.size() - 1; k >= 0 && i < L && j < L; k--)
23       if (P[k][i] == P[k][j]) { i += 1 << k; j += 1 << k; len += 1 << k; }
24     return len; 
25   } 
26 };
View Code

E:

F: 卡题意题(kalili and sadbb done)

G:

H: 归纳总结后dp(sadBB done)

I: 二维树状数组(kalili done)

J:  期望水题(sadBB done)

K: 简单排序后构造(kalili done)

 

posted on 2016-08-31 15:43  Goforworld  阅读(398)  评论(0)    收藏  举报

导航