从一个问题的多个算法看算法的优化
来源:互联网 发布:台达触摸屏编程软件3.0 编辑:程序博客网 时间:2024/06/08 13:30
题目:给定两个数列
算法一:
暴力穷举数列c的所有可能,看
算法二:
我们换个角度来想,算法一之所以复杂度高,是因为数列c的可能性太多了,那问题中有没有哪些值可能性并没有那么多,但只要我们枚举这些值就可以得到答案呢?有,比如
#include <cstdio>const int N = 100 + 10;const int inf = 1000000000;int A[N], B[N];int n;inline bool in_range(int left, int right, int x){ return x >= left && x <= right;}bool check(int left, int right, int& d){ int tmp, i; if (left > right) { tmp = left; left = right; right = tmp; } for (i=0; i<n; i++) if (!in_range(left, right, A[i] + B[i]) && !in_range(left, right, A[i] - B[i])) return false; d = right - left; return true;}int main(){ int res, t, d, i, j, k; scanf("%d", &t); while (t --) { scanf("%d", &n); for (i=0; i<n; i++) scanf("%d", &A[i]); for (i=0; i<n; i++) scanf("%d", &B[i]); if (n == 1) { printf("0\n"); continue; } res = inf; for (i=0; i<n-1; i++) for (j=i+1; j<n; j++) { if (check(A[i] + B[i], A[j] + B[j], d) && d < res) res = d; if (check(A[i] + B[i], A[j] - B[j], d) && d < res) res = d; if (check(A[i] - B[i], A[j] + B[j], d) && d < res) res = d; if (check(A[i] - B[i], A[j] - B[j], d) && d < res) res = d; } printf("%d\n", res); } return 0;}
算法三:
我们再进一步考虑
#include <cstdio>#include <algorithm>using namespace std;const int N = 100 + 10;const int inf = 1000000000;int A[N], B[N];int n;bool check(int left, int& d){ int right, i; right = left; for (i=0; i<n; i++) if (A[i] + B[i] >= left && A[i] - B[i] >= left) right = max(right, min(A[i] + B[i], A[i] - B[i])); else if (A[i] + B[i] >= left) right = max(right, A[i] + B[i]); else if (A[i] - B[i] >= left) right = max(right, A[i] - B[i]); else return false; d = right - left; return true; }int main(){ int res, t, d, i, j; scanf("%d", &t); while (t --) { scanf("%d", &n); for (i=0; i<n; i++) scanf("%d", &A[i]); for (i=0; i<n; i++) scanf("%d", &B[i]); res = inf; for (i=0; i<n; i++) { if (check(A[i] + B[i], d) && d < res) res = d; if (check(A[i] - B[i], d) && d < res) res = d; } printf("%d\n", res); } return 0;}
算法四:
前面的算法,枚举c也好,枚举
#include <cstdio>#include <algorithm>using namespace std;const int N = 100 + 10;const int inf = 1000000000;struct ITEM{ int val, id; ITEM(int val=0, int id=0):val(val), id(id){}};int A[N], B[N], cnt[N];ITEM C[2*N];int n;bool operator < (const ITEM& a, const ITEM& b){ return a.val < b.val;}int main(){ int res, t, s, i, j; scanf("%d", &t); while (t --) { scanf("%d", &n); for (i=0; i<n; i++) scanf("%d", &A[i]); for (i=0; i<n; i++) scanf("%d", &B[i]); for (i=0; i<n; i++) { C[i*2] = ITEM(A[i] + B[i], i); C[i*2+1] = ITEM(A[i] - B[i], i); cnt[i] = 0; } sort(C, C + 2 * n); s = 0; for (i=0; i<2*n; i++) { cnt[C[i].id] ++; if (cnt[C[i].id] == 1) s ++; if (s == n) break; } j = 0; for (; cnt[C[j].id]==2; j++) cnt[C[j].id] --; res = C[i].val - C[j].val; for (i++; i<2*n; i++) { cnt[C[i].id] ++; for (; cnt[C[j].id]==2; j++) cnt[C[j].id] --; res = min(res, C[i].val - C[j].val); } printf("%d\n", res); } return 0;}
总结一下,我们设计和优化算法,常见的思路一个是尽可能的减少可能性,可能性越少,需要枚举的就越少;一个是多变换看待问题的角度,有时换个角度就能更容洞悉问题的本质.
- 从一个问题的多个算法看算法的优化
- 从一个简单查找问题看算法的魅力
- 从一个复数点积算法看NEON的汇编优化(NEON优化实例)
- 从最大子段和问题看算法的优化问题
- 从最大子段和问题看算法的优化问题
- 从最大子段和问题看算法的优化问题
- 从最大子段和问题看算法的优化问题
- 从ZOJ 1666看找零问题的算法
- 从“求最大连续和问题”看算法优化
- 从百元百鸡这个简单问题看算法优化
- 一个小算法的优化
- hdu 1024Max Sum Plus Plus 最大M段字段和 单调优化DP 从一类单调性问题看算法的优化
- 从一道简单的题看算法优化 ZOJ PAT Course List for Student
- AMDD 一个把大问题分成小问题的优化算法
- 连连看算法的一个思路
- 最近看的一个小算法
- 从长度为N的数组中找出所有M个元素组合的优化算法
- 从硬币找零问题:看分治/动态规划/贪心算法的区别与联系
- 一、什么是动态网页、网站?
- Meshlab配置问题2
- 字符串 字符数组
- 排序——快速排序
- chrome 显示IP地址
- 从一个问题的多个算法看算法的优化
- spark资源参数调优
- Q65:滑动窗口的最大值
- cocos2dx-lua用sublime执行exe
- Java开发中的23种设计模式详解(转)
- 两个线程同时调用一个函数会出现什么情况?
- 红黑树
- 10278 FireStation
- Android软键盘手动显示、隐藏、布局上移和EditText上移