几个经典算法
来源:互联网 发布:淘宝网注册支付宝流程 编辑:程序博客网 时间:2024/06/09 15:42
蛮力算法
子集
#include<iostream>using namespace std;#define MAX 1000int main() { int n; int a[MAX]; int tol;//子集的个数 n=4; for(int i=0; i<n; i++) { cin>>a[i]; } tol=(1<<n)-1; //子集的个数 for(int i=0; i<=tol; i++) { for(int j=0; j<n; j++) if(i&(i<<j)) cout<<a[j]; //i<<j相当于对每一个进行标记 cout<<" "<<endl; }}
递归算法
1.输出全排列
#include<iostream>using namespace std;void Perm(int list[],int k,int m) { if(k==m) { for(int i=0; i<=m; i++) cout<<list[i]<<" "; cout<<endl; } else { for(int j=k; j<=m; j++) { swap(list[k],list[j]); Perm(list,k+1,m); swap(list[k],list[j]); } }}int main() { int list[]= {1,2,3,4,5}; Perm(list,0,3);}
//正整数n的划分算法
#include <iostream>using namespace std;int split(int n,int m){ if(n==1||m==1) return 1; else if (n<m) return split(n,n); else if(n==m) return split(n,n-1)+1; else return split(n,m-1)+split(n-m,m);}int main(){ int n; while (cin>>n) cout<<split(n, n)<<endl; return 0;} //对一个段进行递归调用 return select(j+1, right, k-j+left-1); else return select(left, j-1, k);}int main(){ int n, k; while (cin>>n>>k) { for (int i=0; i<n; i++) cin>>a[i]; cout<<select(0, n-1, k)<<endl; } return 0;}
//半数集问题的递归算法
#include<iostream> using namespace std;int a[1001];int comp(int n){ int ans=1; if(a[n]>0)return a[n]; for(int i=1;i<=n/2;i++) ans+=comp(i); a[n]=ans; return ans;}int main(){ int n; while(cin>>n) { memset(a,0,sizeof(a)); a[1]=1; cout<<comp(n)<<endl; } return 0;}
分治算法
选择问题
//采用分治策略找出第k小元素的算法
#include <iostream>using namespace std;#define NUM 1001int a[NUM];int select(int left, int right, int k){ //找到第k小的元素 if (left >= right) return a[left]; int i = left; int j = right+1; //把最左边的元素作为分界数据 int pivot = a[left]; while (true) { do { i = i+1; } while (a[i] < pivot); do { j = j-1; } while (a[j] > pivot); if (i >= j) break; swap(a[i], a[j]); } if (j-left+1 == k) return pivot; a[left] = a[j]; a[j] = pivot; if (j-left+1 < k) return select(j+1,right,k-j+left-1); else return select(left,j-1,k);} 选择第K个大的数#include<iostream>using namespace std;void swap(int *a, int *b){ int tmp; tmp = *a; *a = *b; *b = tmp;}int partition(int arr[], int left, int right, int pivotIndex){ int storeIndex = left; int pivotValue = arr[pivotIndex]; int i; swap(&arr[pivotIndex],&arr[right]); for (i = left; i < right; i ++) { if (arr[i] > pivotValue) { swap(&arr[i],&arr[storeIndex]); storeIndex++; } } swap(&arr[storeIndex],&arr[right]); return storeIndex;}int findKMax(int arr[], int left, int right, int k){ int nRet; int pivotIndex = left + 1; nRet = partition(arr,left,right,pivotIndex); if (nRet < k) { return findKMax(arr,nRet+1,right,k); } else if (nRet > k) { return findKMax(arr,left,nRet-1,k); } return nRet;}int main(){ int i,k,nRet; int arr[] = {8,3,4,1,9,7,6,10}; scanf("%d",&k); nRet = findKMax(arr,0,7,k-1); printf("The Kth Max Number locate in %d is :%d\n",nRet,arr[nRet]); for (i = 0; i < 8; i++) { printf("%3d",arr[i]); } return 0;}
/循环赛程表
#include <stdio.h>#define MAX 100int a[MAX][MAX];void Copy(int tox, int toy, int fromx, int fromy, int r){ for (int i=0; i<r; i++) for (int j=0; j<r; j++) a[tox+i][toy+j] = a[fromx+i][fromy+j];}//构造循环赛日程表,选手的数量n=2^kvoid Table(int k){ int i, r; int n = 1 << k; //构造正方形表格的第一行数据 for (i=0; i<n; i++) a[0][i] = i + 1; //采用分治算法构造整个循环日程赛表 for (r=1; r<n; r<<=1) for (i=0; i<n; i+=2*r) { Copy(r, i + r, 0, i, r); Copy(r, i, 0, i + r, r); }}void Out(int n){ for (int i=0; i<n; i++) { for (int j=0; j<n; j++) printf("%3d", a[i][j]); printf("\n"); } printf("\n");}int main(){ int k; while (scanf("%d", &k) && k) { int n = 1 << k; Table(k); Out(n); } return 0;}
动态规划
矩阵链乘积
#include<iostream>using namespace std;int m[100][100];int p[100],s[100][100];int k;int TraceBack(int i,int j) { if(m[i][j]>0) return m[i][j]; if(i==j) return 0; int u=TraceBack(i,i)+TraceBack(i+1,j)+p[i-1]*p[k]*p[j]; s[i][j]=i; for(int k=i+1; k<j; k++) { int t=TraceBack(i,k)+TraceBack(k+1,j)+p[i-1]*p[k]*p[j]; if(t<u) { u=t; s[i][j]=k; } m[i][j]=u; return u; }}
最多单减子序列
#include<iostream>using namespace std;#define MAX 1000int a[MAX] = {2,1,3};int select(int left,int right,int k) { if(left>=right) return a[left]; int i =left; int j = right+1; int pivot = a[left]; //把第一个设为界点 while(true) { do { i++; } while(a[i]<pivot); do { j--; } while(a[j]>pivot); if(i>=j) break; swap(a[i],a[j]); } if(j-left+1==k) return pivot; //该界点就是要找的数 a[left]=a[j]; a[j]=pivot; if(j-left+1<k) return select(j+1, right, k-j+left-1); else return select(left,j-1,k);}int main() {// int a[3] = {2,1,3}; cout<<select(0,2,2);}
//计算0-1背包的动态规划算法
#include <iostream>#include<ctime>using namespace std;#define NUM 50#define CAP 1500int v[NUM];int w[NUM];int p[NUM][CAP];//形参c是背包的容量w,n是物品的数量void knapsack(int c, int n) { int jMax=min(w[n]-1,c); for( int j=0; j<=jMax; j++) p[n][j]=0; for( int j=w[n]; j<=c; j++) p[n][j]=v[n]; for( int i=n-1; i>1; i--) { jMax=min(w[i]-1,c); for( int j=0; j<=jMax; j++) p[i][j]=p[i+1][j]; for(int j=w[i]; j<=c; j++) p[i][j]=max(p[i+1][j], p[i+1][j-w[i]]+v[i]); } p[1][c]=p[2][c]; if (c>=w[1]) p[1][c]=max(p[1][c], p[2][c-w[1]]+v[1]); } void traceback( int c, int n, int x[ ]) { for(int i=1; i<n; i++) { if (p[i][c]==p[i+1][c]) x[i]=0; else { x[i]=1; c-=w[i]; } } x[n]=(p[n][c])? 1:0; } int main () { int x[NUM]; int W; int n; while (scanf("%d", &W) && W) { scanf("%d", &n); for (int i=1; i<=n; i++) scanf("%d%d", &w[i], &v[i]); memset (p, 0, sizeof(p)); knapsack(W, n); printf("%d\n", p[1][W]); traceback(W, n, x); for (int i=1; i<=n; i++) if (x[i]) printf("%d ", i); printf("\n"); } return 0;}
//计算最大字段和的动态规划算法的最优解
#include <stdio.h>#define NUM 1001int a[NUM];int MaxSum(int n, int &besti, int &bestj){ int sum=0; int b=0; int begin = 0; for (int i=1;i<=n;i++) { if (b>0) b+=a[i]; else {b=a[i];begin = i;} if (b>sum) { sum = b; besti = begin; bestj = i; } } return sum;}int main() { int n; int besti, bestj; while (scanf("%d", &n) && n) { besti = 0; bestj = 0; for (int i=1; i<=n; i++) scanf("%d", &a[i]); printf("%d\n", MaxSum(n, besti, bestj)); printf("From %d to %d\n", besti, bestj); } return 0;}
贪心算法
//删数问题 ,找最近下降点
#include<iostream>#include<String>using namespace std;int main() { string a; int k; cin>>a>>k; if(k>=a.size()) a.erase(); else while(k>0) { int i; for(i=0; (i<a.size()-1)&&a[i]<=a[i+1]; i++); a.erase(i,1); k--; } while(a.size()>1 && a[0]=='0') a.erase(0,1); cout<<a<<endl;}
删数问题
#include<iostream>#include<string>using namespace std;int main(){ string n; int s,i,x,l,m; while(cin>>n>>s) { i=-1,m=0,x=0; l=n.length(); while(x<s&&m==0) { i++; if(n[i]>n[i+1])//出现递减,删除递减的首数字 { n=n.erase(i,1); x++;// x统计删除数字的个数 i=-1;//从头开始查递减区间 } if(i==l-x-2&&x<s) m=1;//已经无递减区间,m=1脱离循环 } cout<<n.substr(0,l-s+x)<<endl;//只打印剩下的左边l-(s-x)个数字 } return 0; }
回溯算法
轮船装载(回溯)
#include<iostream>using namespace std;#define NUM 100 //解空间树 int n; //集装箱数量int c; //轮船装在数量int w[NUM];//集装箱重量数组int x[NUM];//解向量int r; //剩余集装箱重量int cw; //当前轮船载重量int bestw; //当前最优载重量int bestx[NUM];//当前最优解void Backtrack(int t) { //到达叶子节点 if(t>n) { if(cw>bestw) { //更新最优解 for(int i=1; i<=n; i++) bestx[i] = x[i]; bestw = cw; } return; } //更新剩余集装箱的重量 r-= w[t]; //搜索左子树 if(cw+w[t]<=c) { x[t]=1; \ cw+=w[t]; Backtrack(t+1); cw-=w[t];//恢复 状态 } //搜索右子树 if(cw+r>bestw) { x[t]=0; Backtrack(t+1); } r+= w[t];//恢复状态}
N皇后问题
#include<iostream>#include<cmath>using namespace std;#define NUM 20int n=8;int x[NUM]; //记录解向量,列号int sum=0; //解的个数inline bool Place(int t) { int i; for(i=1; i<t; i++) { if((abs(t-i) == abs(x[i]-x[t])) || (x[i]==x[t])) return false; } return true; //只要不满足循环就返回true}void Backtrack(int t) { int i;//叶子节点 if(t>n) { sum++; for(i=1; i<=n; i++) { cout<<x[i]; } cout<<endl; } else { for(i=1; i<=n; i++) { x[t]=i; if(Place(t)) Backtrack(t+1); } }}int main() { //cin>>n; Backtrack(1); cout<<"Total="<<sum<<endl;}
分支限界算法
装载问题分支限界算法的实现
#include<iostream>#include<queue>#include<algorithm>using namespace std;#define NUM 100int n;//集装箱的数量int c;//轮船的载重量int w[NUM];////集装箱的重量数组int MaxLoading(){ queue<int> Q; Q.push(-1); int i = 0; int Ew = 0; int bestw = 0; int r = 0; for(int j=1; j<n; j++) r += w[j]; while (true) { int wt = Ew+w[i]; if (wt<=c) { if (wt>bestw) bestw = wt; if (i<n-1) Q.push(wt); } if (Ew+r>bestw && i<n-1) Q.push(Ew); Ew = Q.front(); Q.pop(); if (Ew==-1) { if (Q.empty()) return bestw; Q.push(-1); Ew = Q.front(); Q.pop(); i++; r -= w[i]; } } return bestw;}int main(){ while(scanf("%d%d", &c, &n)!=EOF) { for(int i=0; i<n; i++) scanf("%d",&w[i]); int ans = MaxLoading(); if (ans) printf("%d\n", ans); else printf("No answer!\n"); } return 0;}
阅读全文
1 0
- 几个经典算法研究
- 几个经典算法
- 几个经典的排序算法
- 几个经典算法的概念
- 几个经典基础算法题目
- 几个经典的中介哈希算法
- 算法设计几个经典思维题目
- C语言几个经典的算法
- 贪心算法及几个经典例子
- 几个经典的动态规划的算法
- 【经典算法】:图的几个应用
- 几个经典的动态规划算法
- 贪心算法及几个经典案例
- 几个面试经典算法题Java解答
- 算法设计与分析绪论学习-几个经典算法
- 终于把dp算法几个经典题目ac了
- 经典算法在几个开源项目中的应用
- 你必须背下的几个经典算法
- Atom 和 VSCode 同一天发布神器:实时编码分享
- 从点击Laucher中的图标开始分析加载一个app的第一个界面的流程
- python 使用opencv 对图像mask处理
- (转载)IE8+兼容经验小结
- 《图解HTTP》读书笔记(7)第7章确保Web安全的HTTPS(关键词:HTTP/HTTPS)
- 几个经典算法
- Cordova App 打包全揭秘
- 生活,寻找幸福的感觉
- Ubuntu下tftp的安装,并使用tftp将文件传输到开发板上面执行
- 什么是阿里云轻量应用服务器?它有什么优点?值得购买吗?
- iOS-Best-Practices, iOS软件设计的最佳实践
- python读取视频流提取视频帧的方法
- 初识数据库——Mysql入门
- Nmap 使用技巧汇总