训练一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 };
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) 收藏 举报
浙公网安备 33010602011771号