几个经典算法
2017-11-17 12:48
344 查看
蛮力算法
子集#include<iostream> using namespace std; #define MAX 1000 int 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); }
2.正整数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; }
3.半数集问题的递归算法
#include<iostream> using namespace std; int a[1001]; int comp(int n) { int ans=1; if(a >0)return a ; for(int i=1;i<=n/2;i++) ans+=comp(i); a =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 1001 int 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 storeIn 10d04 dex = 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 100 int 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^k void 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; }
动态规划
1.矩阵链乘积#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; } }
2.最多单减子序列
#include<iostream> using namespace std; #define MAX 1000 int 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); }
3.计算0-1背包的动态规划算法
#include <iostream> #include<ctime> using namespace std; #define NUM 50 #define CAP 1500 int v[NUM]; int w[NUM]; int p[NUM][CAP]; //形参c是背包的容量w,n是物品的数量 void knapsack(int c, int n) { int jMax=min(w -1,c); for( int j=0; j<=jMax; j++) p [j]=0; for( int j=w ; j<=c; j++) p [j]=v ; 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 =(p [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; }
4.计算最大字段和的动态规划算法的最优解
#include <stdio.h> #define NUM 1001 int 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 20 int 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 100 int 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; }
相关文章推荐
- 你必须背下的几个经典算法[2nd]
- 有关图的几个经典算法
- 几个经典的小算法
- 几个经典基础算法题目
- 算法设计几个经典思维题目
- 经典算法在几个开源项目中的应用
- 务实而深入地理解机器学习的几个经典算法
- 几个经典的算法
- 几个比较经典的算法问题的java实现
- C语言几个经典的算法
- 『OpenCV3』经典目标检测算法中的几个概念
- 整理几个经典的算法,随时更新(排序,去重,斐波那契函数)
- 【经典算法】:图的几个应用
- 几个经典算法的概念
- 数据挖掘几个经典算法
- 几个面试经典算法题Java解答
- 几个经典算法研究
- 黑马程序员----c语言入门疑难点--几个经典的算法
- 几个面试经典算法题Java解答
- 几个经典的字符串操作算法