大白书DP习题
来源:互联网 发布:南京大学知乎 编辑:程序博客网 时间:2024/04/29 05:39
9月7号~
开学啦,时间有点紧张。。
暑假算是白费啦~
今天开始刷大白书DP习题。。
一天一个!
废话不多说。。开刷!
Partitioning by Palindromes
第一天~
题目传送:UVA - 11584 - Partitioning by Palindromes
分类:DP入门题。
分析:因为是考虑回文串,很容易想到用两个指针来找以当前点为中点的回文串,每次找到一个回文串就进行更新,不过要注意偶数回文和奇数回文的情况
WA了两次,没注意到每次找到回文串都要更新还有刚开始需要更新一下。。
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;char s[1005];int dp[1005];//dp[i]表示以i为结尾的子串能够划分的最少回文串int main() { int n; s[0] = '$'; scanf("%d", &n); while(n -- ) { scanf("%s", s + 1); int len = strlen(s + 1); for(int i = 0; i <= len; i ++) dp[i] = i; for(int i = 1; i <= len; i ++) { int p = i - 1, q = i + 1;//左右两个指针 int l = 1;//s[i]为中点时的回文串的长度 dp[i] = min(dp[i], dp[p] + 1);//记得更新所有可能的情况 while(s[i] == s[q] && q <= len) { l ++; q ++; dp[q - 1] = min(dp[q - 1], dp[p] + 1);//记得每走一步都要记得更新一下,不然只更新最后一步会错,比如bdbacabcb } while(p >= 0 && q <= len && s[p] == s[q]) { l += 2; p --; q ++; dp[q - 1] = min(dp[q - 1], dp[p] + 1); } dp[q - 1] = min(dp[q - 1], dp[p] + 1); } printf("%d\n", dp[len]); } return 0;}
Salesmen
第二天~
题目传送:UVALive - 4256 - Salesmen
分类:DP入门题。
分析:数据比较小,直接考虑暴力递推之。。
此题较顺利,,1A。
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0xfffffffusing namespace std;int n, n1, n2;int mp[105][105];int A[205];int dp[205][105];//dp[i][j]表示序列中第i个数字为j时需要修改的最少的数int main() { int T; scanf("%d", &T); while(T --) { memset(mp, 0, sizeof(mp)); scanf("%d %d", &n1, &n2); int u, v; for(int i = 0; i < n2; i ++) { scanf("%d %d", &u, &v); mp[u][v] = 1; mp[v][u] = 1; } for(int i = 1; i <= n1; i ++) mp[i][i] = 1; scanf("%d", &n); for(int i = 1; i <= n; i ++) { scanf("%d", &A[i]); } //初始化 for(int i = 0; i < 205; i ++) { for(int j = 0; j < 105; j ++) { dp[i][j] = INF; } } for(int i = 1; i <= n1; i ++) { if(i != A[1]) dp[1][i] = 1; else dp[1][i] = 0; } //DP递推 for(int p = 2; p <= n; p ++) {//枚举序列的第几个位置 for(int i = 1; i <= n1; i ++) {//枚举该位置的每个可能取值 if(i != A[p]) {//此位置改变 for(int j = 1; j <= n1; j ++) { if(mp[i][j] == 1) { dp[p][i] = min(dp[p][i], dp[p-1][j] + 1); } } } else if(i == A[p]) { for(int j = 1; j <= n1; j ++) { if(mp[i][j] == 1) { dp[p][i] = min(dp[p][i], dp[p-1][j]); } } } } } //for(int i = 1; i <= n; i ++) { // for(int j = 1; j <= n1; j ++) { // cout << dp[i][j] << " "; // } // cout << endl; //} int ans = INF; for(int i = 1; i <= n1; i ++) { ans = min(ans, dp[n][i]); } printf("%d\n", ans); } return 0;}
Wavio Sequence
第三天~
题目传送:UVA - 10534 - Wavio Sequence
分类:序列型DP(最长上升子序列)
分析:根据题目意思,可以知道只需要考虑每一个点作为中点时,维护往前的最长上升子序列,和往后的最长下降子序列即可,两个一前一后的子序列之间只要取较小的那个值就是此点的k+1,则更新答案ans = max(ans, 2* (k + 1) - 1)。1A。
其中最长上升子序列用了lower_bound,复杂度为O(n*logn)。
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;int n;int dp1[10005];//dp1[i]表示从1到i的i个数中的最长上升子序列int dp2[10005];//dp2[i]表示从i到n的n-i+1个数中的最长下降子序列int a[10005];int g[10005];//辅助数组int main() { while(scanf("%d", &n) != EOF) { for(int i = 1; i <= n; i ++) { scanf("%d" , &a[i]); } for(int i = 1; i <= n; i ++) g[i] = INF; for(int i = 1; i <= n; i ++) { int k = lower_bound(g + 1, g + n + 1, a[i]) - g; g[k] = a[i]; dp1[i] = k; } for(int i = 1; i <= n; i ++) g[i] = INF; for(int i = n; i >= 1; i --) { int k = lower_bound(g + 1, g + n + 1, a[i]) - g; g[k] = a[i]; dp2[i] = k; } int ans = 0; for(int i = 1; i <= n; i ++) { int t = min(dp1[i], dp2[i]); ans = max(ans, t * 2 - 1); } printf("%d\n", ans); } return 0;}
Fewest Flops
第四天~
题目传送:UVA - 11552 - Fewest Flops
分类:简单DP,重在设计状态以及状态怎么转移
分析:分成len/k个组就行了,然后定义dp[i][j]表示第i组以j结尾时的最小块数。然后递推即可,注意递推的时候要判断当前状态和前一状态是否存在这个字母,不然会出错,这里分别WA了一下。
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffff#define min(a, b) (a) < (b) ? (a) : (b)using namespace std;int k;char s[1005];int d[1005][26];//d[i][0~25]代表第i个组内是否存在a~z这些字母int cnt[1005];//cnt[i]代表第i组有多少个不同的字母int dp[1005][26];//d[i][0~25]代表第i个组以a~z结尾时的最小块数int main() { int T; scanf("%d", &T); while(T --) { memset(cnt, 0, sizeof(cnt)); memset(d, 0, sizeof(d)); scanf("%d %s", &k, s); int len = strlen(s); int zu = len / k; int p = 0; for(int i = 1; i <= zu; i ++) { for(int j = 0; j < k; j ++, p ++) { if(d[i][s[p] - 'a'] == 0) { cnt[i] ++; d[i][s[p] - 'a'] = 1; } } } //for(int i = 1; i <= zu; i ++) cout << cnt[i] << " "; cout << endl; //边界 for(int i = 0; i <= zu; i ++) { for(int j = 0; j < 26; j ++) { dp[i][j] = INF; } } for(int i = 0; i < 26; i ++) { dp[1][i] = cnt[1]; } //递推 for(int i = 2; i <= zu; i ++) { for(int j = 0; j < 26; j ++) {//递推当前的26个字母 if(d[i][j] == 1) {//判断当前是否存在j这个字母 for(int k = 0; k < 26; k ++) {//递推前一个状态的26个字母 if(d[i-1][k]) {//判断前一个状态是否存在k这个字母 if((d[i][k] == 1 && k != j) || (d[i][k] == 1 && k == j && cnt[i] == 1)) { dp[i][j] = min(dp[i][j], dp[i-1][k] + cnt[i] - 1); } else dp[i][j] = min(dp[i][j], dp[i-1][k] + cnt[i]); } } } } } int ans = INF; //for(int i = 1; i <= zu; i ++) { // for(int j = 0; j < 26; j ++) { // cout << dp[i][j] << " "; // } // cout << endl; //} for(int i = 0; i < 26; i ++) { ans = min(ans, dp[zu][i]); } printf("%d\n", ans); } return 0;}
Palindromic Subsequence
第五天~
题目传送:UVA - 11404 - Palindromic Subsequence
分类:序列型DP
分析:就是类似的LCS问题,如果输出长度就很简单,不过这里要输出回文串,想了半天不知怎么存,无奈搜了下题解,原来这里可以写在一个结构体里面来记录最小字典序,还要注意那个最小字典序可能不是回文串,需要奇偶分别判断一下输出
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;const int maxn = 1005;struct node { int len; string str;}dp[maxn][maxn];//类似LCS的dp,只不过加上了此时的最小字典序char s1[maxn];char s2[maxn];int n, len;int main() { while(scanf("%s", s1 + 1) != EOF) { len = strlen(s1 + 1); s2[len + 1] = '\0'; for(int i = 1; i <= len; i ++) { s2[len - i + 1] = s1[i]; } //初始化 for(int i = 0; i <= len; i ++) { dp[0][i].len = 0; dp[0][i].str = ""; } //printf("%s %s\n", s1 + 1, s2 + 1); //递推 for(int i = 1; i <= len; i ++) { for(int j = 1; j <= len; j ++) { if(s1[i] == s2[j]) { dp[i][j].len = dp[i-1][j-1].len + 1; dp[i][j].str = dp[i-1][j-1].str + s1[i]; } else { if(dp[i-1][j].len > dp[i][j-1].len) { dp[i][j].len = dp[i-1][j].len; dp[i][j].str = dp[i-1][j].str; } else if(dp[i][j-1].len > dp[i-1][j].len) { dp[i][j].len = dp[i][j-1].len; dp[i][j].str = dp[i][j-1].str; } else { dp[i][j].len = dp[i-1][j].len; dp[i][j].str = min(dp[i-1][j].str, dp[i][j-1].str); } } } } int ma = dp[len][len].len; string ans = dp[len][len].str; if(ma & 1) { for(int i = 0; i < ma / 2; i ++) { cout << ans[i]; } for(int i = ma / 2; i >= 0; i --) { cout << ans[i]; } cout << endl; } else { for(int i = 0; i < ma / 2; i ++) { cout << ans[i]; } for(int i = ma / 2 - 1; i >= 0; i --) { cout << ans[i]; } cout << endl; } } return 0;}
Cellular Network
第六天~
有点累。。
题目传送:UVALive - 4731 - Cellular Network
分类:贪心+概率DP
分析:根据递推式可以很清楚的知道要将概率先从大到小排序,因为要尽可能小。
此外,设dp[i][j]表示前i个分成j组的最小期望值,递推即可
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;double dp[105][105];//dp[i][j]表示前i个分成j组的最小值double u[105];double p[105];double qzh[105];int n, w;bool cmp(double a, double b) { return a > b;}int main() { int T; scanf("%d", &T); while(T --) { scanf("%d %d", &n, &w); double sum = 0; for(int i = 1; i <= n; i ++) { scanf("%lf", &u[i]); sum += u[i]; } for(int i = 1; i <= n; i ++) { p[i] = u[i] / sum; } sort(p + 1, p + n + 1, cmp); //for(int i = 1; i <= n; i ++) cout << p[i] << " "; cout << endl; for(int i = 1; i <= n; i ++) { qzh[i] = qzh[i-1] + p[i]; } for(int i = 1; i <= n; i ++) {//递推前i个 dp[i][1] = i * qzh[i]; for(int j = 2; j <= w && j <= i; j ++) {//分成j组 dp[i][j] = INF; for(int k = j - 1; k < i; k ++) {//枚举前一状态k个分为j-1组时的情况 dp[i][j] = min(dp[i][j], dp[k][j-1] + i * (qzh[i] - qzh[k])); } } } printf("%.4lf\n", dp[n][w]); } return 0;}
Mega Man’s Mission
第七天~
题目传送:UVA - 11795 - Mega Man’s Mission
分类:状态压缩DP
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;const int maxn = (1 << 16) + 5;int n;LL dp[maxn];//dp[i]表示状态为i时的顺序总数int kill[maxn];//kill[i]表示状态为i时可以消灭的机器人int wuqi[35];//武器属性int main() { int T; scanf("%d", &T); for(int cas = 1; cas <= T; cas ++) { memset(wuqi, 0, sizeof(wuqi)); char s[35]; scanf("%d", &n); for(int i = 0; i <= n; i ++) { scanf("%s", s); wuqi[i] = 0; for(int j = 0; s[j]; j ++) { if(s[j] == '1') { wuqi[i] |= (1 << j); } } } int tot = (1 << n) - 1; kill[0] = wuqi[0]; for(int s = 1; s <= tot; s ++) { kill[s] = wuqi[0]; for(int i = 1; i <= n; i ++) { if(s & (1 << (i - 1))) kill[s] |= wuqi[i]; } } memset(dp, 0, sizeof(dp)); dp[0] = 1;//一个机器人都不杀的方案为1 for(int i = 1; i <= tot; i ++) {//枚举全集 for(int j = 1; j <= n; j ++) {//枚举当前集合去掉第j个机器人的子集 if(i & (1 << (j -1))) { int zi = i ^ (1 << (j - 1)); if(kill[zi] & (1 << (j - 1))) { dp[i] += dp[zi]; } } } } //for(int i = 0; i <= tot; i ++) { // printf("%d %d %d\n", i, dp[i], wuqi[i]); //} printf("Case %d: %lld\n", cas, dp[tot]); } return 0;}
Jump
第八天~
有点破事,,隔了一天才弄
题目分类:变形的Joseph问题
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;const int maxn = 500005;int f[maxn];int a[5];int n, k;int main() { int T; scanf("%d", &T); while(T --) { scanf("%d %d", &n, &k); for(int i = 1; i <= 3; i ++) { f[i] = (k - 1) % i; for(int j = i + 1; j <= n; j ++) f[j] = (f[j - 1] + k) % j; a[i] = (1 + f[n]) % n; if(a[i] <= 0) a[i] += n; } printf("%d %d %d\n", a[3], a[2], a[1]); } return 0;}
Martian Mining
第九天~
题目传送:UVALive - 3530 - Martian Mining
有点累了,直接上代码吧。。
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;const int maxn = 505;int n, m;int A[maxn][maxn];int B[maxn][maxn];int dpa[maxn][maxn];//dpa[i][j]表示以i,j为右下角,1,1为左上角所围成的矩形里,在i,j这个点运输A可以得到的最大值int dpb[maxn][maxn];//dpb[i][j]表示以i,j为右下角,1,1为左上角所围成的矩形里,在i,j这个点运输B可以得到的最大值int sum_row[maxn][maxn];int sum_col[maxn][maxn];int main() { while(scanf("%d %d", &n, &m) != EOF) { if(n == 0 && m == 0) break; memset(dpa, 0, sizeof(dpa)); memset(dpb, 0, sizeof(dpb)); for(int i = 1; i <= n; i ++) { for(int j = 1; j <= m; j ++) { scanf("%d", &A[i][j]); sum_row[i][j] = sum_row[i][j-1] + A[i][j]; } } for(int i = 1; i <= n; i ++) { for(int j = 1; j <= m; j ++) { scanf("%d", &B[i][j]); sum_col[i][j] = sum_col[i-1][j] + B[i][j]; } } for(int i = 1; i <= n; i ++) { for(int j = 1; j <= m; j ++) { dpa[i][j] = max(dpa[i-1][j], dpb[i-1][j]) + sum_row[i][j]; dpb[i][j] = max(dpa[i][j-1], dpb[i][j-1]) + sum_col[i][j]; } } printf("%d\n", max(dpa[n][m], dpb[n][m])); } return 0;}
Paths through the Hourglass
第十天~
题目传送:UVA - 10564 - Paths through the Hourglass
啊啊啊啊啊,,不行了啊,,感觉做不动了,,虽然这个还是比较水的题。。因为没有注意到有个地方要反过来,,萎了好久好久。。。
分类:类似01背包的题
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;const int maxn = 385;int n, S;int a[45][25];LL dp[45][25][maxn];//dp[i][j][k]的值表示在位置i,j的时候,选了位于i,j的数时有多少路径上的数之和等于k(这里是逆推)int main() { while(scanf("%d %d", &n, &S) != EOF) { if(n == 0 && S == 0) break; for(int i = 1; i <= n; i ++) { for(int j = 1; j <= n - i + 1; j ++) { scanf("%d", &a[i][j]); } } for(int i = n + 1; i <= 2 * n - 1; i ++) { for(int j = 1; j <= i - n + 1; j ++) { scanf("%d", &a[i][j]); } } if(S >= 360) { printf("0\n\n"); continue; } //因为要打印路径,,所以采用逆推比较好 memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i ++) { dp[2 * n - 1][i][a[2 * n - 1][i]] = 1; } for(int i = 2 * n - 2; i >= n; i --) { for(int j = 1; j <= i - n + 1; j ++) { for(int k = S; k >= 0; k --) { dp[i][j][k + a[i][j]] += dp[i + 1][j][k] + dp[i + 1][j + 1][k]; } } } for(int i = n - 1; i >= 1; i --) { for(int j = 1; j <= n - i + 1; j ++) { for(int k = S; k >= 0; k --) { dp[i][j][k + a[i][j]] += dp[i + 1][j - 1][k] + dp[i + 1][j][k]; } } } LL cnt = 0; for(int i = 1; i <= n; i ++) { cnt += dp[1][i][S]; } cout << cnt << endl; if(cnt == 0) { cout << endl; continue; } int p; for(int i = 1; i <= n; i ++) { if(dp[1][i][S] >= 1) { p = i; break; } } printf("%d ", p - 1); int prev = S;//打印路径 for(int i = 2; i <= n; i ++) { if(dp[i][p-1][S-a[i-1][p]]) { cout << 'L'; S -= a[i-1][p]; p = p - 1; } else { cout << 'R'; S -= a[i-1][p]; } } for(int i = n + 1; i <= 2 * n - 1; i ++) { if(dp[i][p][S-a[i-1][p]]) { cout << 'L'; S -= a[i-1][p]; } else { cout << 'R'; S -= a[i-1][p]; p = p + 1; } } cout << endl; } return 0;}
Strategic game
第11天~
题目传送:UVALive - 2038 - Strategic game
题目分类:树形DP
题目分析:
基础的树形DP(最小顶点覆盖)
首先定义:
- dp[i][0]代表以i为根节点的子树,不选根节点时所需要的最小点数。
- dp[i][1]代表以i为根节点的子树,选根节点时所需要的最小点数。
先考虑不选根节点时,因为要覆盖所有边,所以他的子节点都要选。
再考虑选了根节点时,此时,他的子节点可选可不选,取较小的那个即可。则有状态转移方程:
- dp[u][0] =
∑ dp[v][1] (v为u的子节点)- dp[u][1] =
∑ min(dp[v][0], dp[v][1]) (v为u的子节点)
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;const int maxn = 1505;int n;vector<int> G[maxn];int dp[maxn][2];//dp[i][0]表示以i为根的子树的根节点不选的情况,dp[i][1]表示以i为根的子树的根节点选了的情况void dfs(int u, int fa) { dp[u][0] = 0; dp[u][1] = 1; int d = G[u].size(); for(int i = 0; i < d; i ++) { int v = G[u][i]; if(v != fa) { dfs(v, u); } } for(int i = 0; i < d; i ++) { int v = G[u][i]; if(v != fa) { dp[u][0] += dp[v][1]; dp[u][1] += min(dp[v][0], dp[v][1]); } }}int main() { while(scanf("%d", &n) != EOF) { for(int i = 0; i <= n; i ++) { G[i].clear(); } int u, v, t; for(int i = 0; i < n; i ++) { scanf("%d:(%d)", &u, &t); for(int i = 1; i <= t; i ++) { scanf("%d", &v); G[u].push_back(v); G[v].push_back(u); } } memset(dp, 0, sizeof(dp)); dfs(0, -1); printf("%d\n", min(dp[0][0], dp[0][1])); } return 0;}
- 大白书DP习题
- 动态规划练习题:大白书基础习题
- 大白 数学专题 部分例题习题总结
- 大白书 第三页
- 大白
- 计算几何模板 - 大白书
- 大白书在路上了
- 大白书伸展树学习笔记
- 大白书 1.1节 思维的体操
- dp基础习题(4.11)
- dp基础习题(4.13)
- UVA 10723 LCS变形 dp 紫书习题9-6
- UVa1632 dp 滚动数组 紫书习题9-8
- UVa 11292(今天开始刷大白书了)
- 大白书练习题(持续更新……)UVa & livearchive
- 大白书—数学基础—基础题
- 计算几何模板(仿照刘汝佳大白书风格)
- 大白书109页问题一系列巧妙的递推
- 深入理解7816协议(3)-----关于T=0
- 排队系统的需求分析
- 基础算法(一) ———— 合并两个有序数组
- C++ 之 extern 小结
- Mysql开发规范和原则
- 大白书DP习题
- Linux上虚拟网络与真实网络的映射
- 感动
- Codeforces 575G Run for beer 最短路
- HDU5430欧拉函数求小于等于n的数中与n互质的数的数目
- POI-----单元格常用样式
- 数据结构与算法(C#版)第二章 C#语言与面向对象技术(上)V1.0
- SharedPreference的简单封装备份
- Play on Words