├── P100_Loading.cpp ├── P13_Perm.cpp ├── P13_perm.py ├── P14_q.cpp ├── P14_q.py ├── P15_Hanoi.cpp ├── P15_hanoi.py ├── P17_binary_search.py ├── P24_QuickSort.cpp ├── P24_QuickSort_Split.cpp ├── P25_RandomizedQuickSort.cpp ├── P27_RandomizedSelect.cpp ├── P47_MatriMultiply.cpp ├── P49_MatrixChain.cpp ├── P54_LCS.cpp ├── P54_LCS.py ├── P57_MaxSum.cpp ├── P57_maxsum.py ├── P68_Compress.cpp ├── P71_MNS.cpp ├── P75_Knapsack.cpp ├── P96_GreedySelector.cpp ├── README.assets ├── 0-1背包问题1.png ├── 0-1背包问题2.png ├── 0-1背包问题3.png ├── 图像压缩1.png ├── 图像压缩2.png ├── 图像压缩3.png ├── 快速排序1.png ├── 快速排序2.png ├── 快速排序3.png ├── 快速排序4.png ├── 最优装载1.png ├── 最优装载2.png ├── 最优装载3.png ├── 最大子段和1.png ├── 最大子段和2.png ├── 最大子段和3.png ├── 最大子段和4.png ├── 最长公共子序列1.png ├── 最长公共子序列2.png ├── 最长公共子序列3.png ├── 活动安排问题1.png ├── 活动安排问题2.png ├── 活动安排问题3.png ├── 电路布线1.png ├── 电路布线2.png ├── 电路布线3.png ├── 电路布线4.png ├── 矩阵连乘问题1.png ├── 矩阵连乘问题2.png ├── 矩阵连乘问题3.png └── 矩阵连乘问题4.png └── README.md /P100_Loading.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class SortIndices{ 6 | private: 7 | int* mparr; 8 | public: 9 | SortIndices(int* parr) 10 | :mparr(parr) 11 | {} 12 | bool operator()(int i,int j)const{ 13 | return mparr[i]// 使用模板以支持整型及浮点型 18 | int* Loading(int x[],Type w[],Type c,int n){ 19 | int *t=new int [n+1]; 20 | for(int i=1;i<=n;i++) 21 | t[i]=i; 22 | sort(t+1,t+n+1,SortIndices(w));// 左闭右开,排序范围等价于[t+1,t+n] 23 | for(int i=1;i<=n;i++) 24 | x[i]=0; 25 | for(int i=1;i<=n && w[t[i]]<=c;i++){ 26 | x[t[i]]=1; 27 | c-=w[t[i]]; 28 | } 29 | return t; 30 | } 31 | 32 | int main(){ 33 | const int n=8; 34 | int x[n+1]; 35 | int w[n+1]={0,100,200,50,90,150,50,20,80}; 36 | int c=400; 37 | 38 | int* t=Loading(x,w,c,n); 39 | 40 | 41 | printf("%-8c|",'i'); 42 | for(int i=1;i<=n;i++) 43 | printf("%6d",i); 44 | printf("\n"); 45 | 46 | printf("w[t[i]] |"); 47 | for(int i=1;i<=n;i++) 48 | printf("%6d",t[i]); 49 | printf("\n"); 50 | 51 | printf("loaded |"); 52 | int loaded=0; 53 | for(int i=1;i<=n && x[t[i]]==1;i++){ 54 | loaded+=w[t[i]]; 55 | printf("%6d",loaded); 56 | } 57 | printf("\n"); 58 | 59 | printf("\nx=(%d",x[1]); 60 | for(int i=2;i<=n;i++) 61 | printf(",%d",x[i]); 62 | printf(")"); 63 | return 0; 64 | } -------------------------------------------------------------------------------- /P13_Perm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void Perm(int list[],int k,int m){ 5 | if(k==m){ 6 | for(int i=0;i<=m;i++) 7 | cout<None: 4 | if k==m: 5 | for i in range(m+1): 6 | print(ls[i],end='') 7 | print() 8 | else: 9 | for i in range(k,m+1): 10 | ls[k],ls[i]=ls[i],ls[k] 11 | perm(ls,k+1,m) 12 | ls[k],ls[i]=ls[i],ls[k] 13 | 14 | def main(): 15 | ls=[1,2,3] 16 | perm(ls,0,2) 17 | 18 | if __name__=="__main__": 19 | main() 20 | -------------------------------------------------------------------------------- /P14_q.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int q(int n,int m){ 5 | if(n<1||m<1) 6 | return 0; 7 | if(n==1||m==1) 8 | return 1; 9 | if(nint: 2 | if n<1 or m<1: 3 | return 0 4 | if n==1 or m==1: 5 | return 1 6 | if nint: 13 | return q(n,n) 14 | 15 | def main(): 16 | x=6 17 | print(p(x)) 18 | 19 | if __name__=="__main__": 20 | main() -------------------------------------------------------------------------------- /P15_Hanoi.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | //#define VNAME(value) (#value) 4 | using namespace std; 5 | 6 | 7 | void Move(stack &a,stack &b){ 8 | b.push(a.top()); 9 | a.pop(); 10 | return ; 11 | } 12 | 13 | void Hanoi(int n,stack &a,stack &b,stack &c){ 14 | if(n>0){ 15 | Hanoi(n-1,a,c,b); 16 | Move(a,b); 17 | Hanoi(n-1,c,b,a); 18 | } 19 | return ; 20 | } 21 | 22 | void StackPrint(stack s){ 23 | //cout< dump=s;!dump.empty();dump.pop()) 25 | cout< a,b,c; 31 | int n=3; 32 | for(int i=n;i>0;i--) 33 | a.push(i); 34 | 35 | cout<<"a:"; 36 | StackPrint(a); 37 | cout<<"b:"; 38 | StackPrint(b); 39 | cout<<"c"; 40 | StackPrint(c); 41 | 42 | Hanoi(n,a,b,c); 43 | cout<<"a:"; 44 | StackPrint(a); 45 | cout<<"b:"; 46 | StackPrint(b); 47 | cout<<"c"; 48 | StackPrint(c); 49 | return 0; 50 | } -------------------------------------------------------------------------------- /P15_hanoi.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | def move(a:List,b:List)->None: 4 | temp=a.pop() 5 | b.append(temp) 6 | 7 | def hanoi(n:int,a:List,b:List,c:List)->None:#para3:借用柱 8 | if n>0: 9 | hanoi(n-1,a,c,b) 10 | move(a,b) 11 | globalPrint() 12 | hanoi(n-1,c,b,a) 13 | 14 | a,b,c=[],[],[] 15 | 16 | def globalPrint(): 17 | print(a,b,c) 18 | 19 | def main(): 20 | n=3 21 | for i in range(n,0,-1): 22 | a.append(i) 23 | hanoi(n,a,b,c) 24 | 25 | if __name__=="__main__": 26 | main() -------------------------------------------------------------------------------- /P17_binary_search.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | def binary_search(a:List,x,n:int)->int: 4 | left,right=0,n-1 5 | while left<=right: 6 | middle=(left+right)>>1 7 | if x==a[middle]: 8 | return middle 9 | if x>a[middle]: 10 | left=middle+1 11 | else: 12 | right=middle-1 13 | return -1 14 | 15 | def main(): 16 | ls=sorted([1,4,6,2,36,71,6,3,6,8,4,456]) 17 | print(ls) 18 | print(binary_search(ls,36,len(ls))) 19 | 20 | if __name__=="__main__": 21 | main() -------------------------------------------------------------------------------- /P24_QuickSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | template 6 | int Partition(Type a[],int p,int r){ 7 | int i=p,j=r+1; // 待排区间[p+1,r] 8 | Type x=a[p]; // 基准元素 9 | while(true){ 10 | while(a[++i]=x,t=i+1,i+2,...,r-1(后面所有的元素都比基准元素大)的情况,可能越界,即脱离待排数组,需要约束该向右指针以防该情况发生,出于效率我认为可以改做ix) // 左侧必定存在元素<=x,不会越界 13 | ; 14 | if(i>=j) 15 | break; 16 | swap(a[i],a[j]); 17 | } 18 | // swap(a[p],a[j]); 19 | a[p]=a[j]; 20 | a[j]=x; 21 | return j; 22 | } 23 | 24 | template 25 | void QuickSort(Type a[],int p,int r){ 26 | if(p 2 | #include 3 | using namespace std; 4 | 5 | template 6 | int Split(Type a[],int p,int r){ 7 | int i=p; 8 | Type x=a[p]; 9 | for(int j=p+1;j<=r;j++) 10 | if(x>a[j] && ++i!=j) 11 | swap(a[i],a[j]); 12 | // swap(a[i],a[p]); // 标准的Split算法 13 | // 模拟手算的Split算法 14 | for(int j=p;j 20 | void QuickSort(Type a[],int p,int r){ 21 | if(p 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | template 8 | Type Random(Type p,Type r){ 9 | random_device rd; 10 | default_random_engine e(rd()); 11 | uniform_int_distribution u(p, r); 12 | Type x=u(e); 13 | return x; 14 | } 15 | 16 | template 17 | int Partition(Type a[],int p,int r){ 18 | int i=p,j=r+1; 19 | while(true){ 20 | while(a[++i]a[p]) 23 | ; 24 | if(i>=j) 25 | break; 26 | swap(a[i],a[j]); 27 | } 28 | swap(a[p],a[j]); 29 | return j; 30 | } 31 | 32 | template 33 | int RandomizedPartition(Type a[],int p,int r){ 34 | int i=Random(p,r); 35 | swap(a[i],a[p]); 36 | return Partition(a,p,r); 37 | } 38 | 39 | template 40 | void RandomizedQuickSort(Type a[],int p,int r){ 41 | if(p 60 | void RandomizedQuickSort(vector& a,int p,int r){ 61 | // 将向量转为数组 62 | int arr[a.size()]; 63 | copy(a.begin(),a.end(),arr); 64 | // 调用数组的随机化的快速排序算法 65 | RandomizedQuickSort(arr,p,r); 66 | // 将排序后的数组转为向量 67 | vector varr(arr, arr+a.size()); // 拷贝指针的范围左闭右开,arr+a.size()是已知数组长度(原向量长度)的做法,数组长度大多数时候需要计算,即结束指针使用arr+sizeof(arr)/sizeof(arr[0]) 68 | // 赋值回向量 69 | a=varr; 70 | } 71 | 72 | int main(){ 73 | const int n=8; 74 | vector a={0,8,4,1,7,11,5,6,9}; // C++98 STL 75 | // int *a=new int[n+1]{0,8,4,1,7,11,5,6,9}; // C++11 76 | // int a[n+1]={0,8,4,1,7,11,5,6,9}; // C99 77 | 78 | printf("Original a={%d",a[1]); 79 | for(int i=2;i<=n;i++) 80 | printf(",%d",a[i]); 81 | printf("}\n\n"); 82 | 83 | RandomizedQuickSort(a,1,n); 84 | 85 | printf("\nResult a={%d",a[1]); 86 | for(int i=2;i<=n;i++) 87 | printf(",%d",a[i]); 88 | printf("}"); 89 | 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /P27_RandomizedSelect.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | template 7 | Type Random(Type p,Type r){ 8 | random_device rd; 9 | default_random_engine e(rd()); 10 | uniform_int_distribution u(p, r); 11 | Type x=u(e); 12 | return x; 13 | } 14 | 15 | template 16 | int Partition(Type a[],int p,int r){ 17 | int i=p,j=r+1; 18 | while(true){ 19 | while(a[++i]a[p]) 22 | ; 23 | if(i>=j) 24 | break; 25 | swap(a[i],a[j]); 26 | } 27 | swap(a[p],a[j]); 28 | return j; 29 | } 30 | 31 | template 32 | int RandomizedPartition(Type a[],int p,int r){ 33 | int i=Random(p,r); 34 | swap(a[i],a[p]); 35 | return Partition(a,p,r); 36 | } 37 | 38 | template 39 | void RandomizedQuickSort(Type a[],int p,int r){ 40 | if(p 48 | Type RandomizedSelect(Type a[],int p,int r,int k){ 49 | if(p==r) 50 | return a[p]; 51 | int i=RandomizedPartition(a,p,r); 52 | int j=i-p+1; 53 | if(k<=j) 54 | return RandomizedSelect(a,p,i,k); 55 | else 56 | return RandomizedSelect(a,i+1,r,k-j); 57 | } 58 | 59 | int main(){ 60 | const int n=22; 61 | int k=5; // k在一些情况下会导致随机数引擎段错误,很迷啊席八,换C里面的rand()也一样,考完试再想(估计不会了) 62 | int* a=new int [n+1]{0,2,6,9,1,4,10,20,6,22,11,10,9,4,3,7,16,11,8,2,5,4,1}; 63 | int ak=RandomizedSelect(a,1,n,k); 64 | RandomizedQuickSort(a,1,n); 65 | 66 | printf("a[i]|"); 67 | for(int i=1;i<=n;i++) 68 | printf("%3d",a[i]); 69 | printf("\n"); 70 | 71 | printf(" i |"); 72 | for(int i=1;i<=n;i++) 73 | printf("%3d",i); 74 | printf("\n"); 75 | 76 | printf("The %d-th smallest element is %d",k,ak); 77 | return 0; 78 | } -------------------------------------------------------------------------------- /P47_MatriMultiply.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | bool MatriMultiply(int **a,int **b,int **c,int ra,int ca,int rb,int cb){ 4 | if(ca!=rb){ 5 | perror("矩阵不可乘"); 6 | exit(EXIT_FAILURE);// #define EXIT_FAILURE 1 7 | } 8 | for(int i=0;i 2 | void MatrixChain(int *p,int n,int **m,int **s){ 3 | for (int i=1;i<=n;i++) 4 | m[i][i]=0; 5 | for (int r=2;r<=n;r++){ 6 | for (int i=1;i<=n-r+1;i++){ 7 | int j=i+r-1; 8 | // 打擂法初始化 9 | int k=i; 10 | m[i][j]=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];//m[i][i]=0,所以可以不写 11 | s[i][j]=i; 12 | for (int k=i+1;k 2 | #include 3 | #include 4 | using namespace std; 5 | void LCSLength(int m,int n,char *x,char *y,int **c,int **b){ 6 | int i,j; 7 | // 这里要改,不然c[0][0]初始化不到,其实为了完整性(好看)b也该初始化的 8 | // 初始化第0列 9 | for(int i=0;i<=m;i++){ 10 | c[i][0]=0; 11 | b[i][0]=0; 12 | } 13 | // 初始化第0行 14 | for(int i=0;i<=n;i++){ 15 | c[0][i]=0; 16 | b[0][i]=0; 17 | } 18 | for(i=1;i<=m;i++){ 19 | for(j=1;j<=n;j++){ 20 | // 从左到右 从上到下遍历 21 | // 对一个4格的右下格子 22 | // 如果匹配上了,从左上格子转移 23 | // 这里要改,序列的索引应从0起 24 | if(x[i-1]==y[j-1]){ 25 | c[i][j]=c[i-1][j-1]+1; 26 | b[i][j]=1; 27 | } 28 | // 如果没匹配上 29 | // 且上方格子大于(等于)左方格子,从上方格子转移 30 | else if(c[i-1][j]>=c[i][j-1]){ 31 | c[i][j]=c[i-1][j]; 32 | b[i][j]=2; 33 | } 34 | // 且左方格子大于上方格子,从左方格子转移 35 | else{ 36 | c[i][j]=c[i][j-1]; 37 | b[i][j]=3; 38 | } 39 | } 40 | } 41 | } 42 | 43 | void LCS(int i,int j,char *x,int **b){ 44 | // 如果递归至边界,结束 45 | if(i==0||j==0) 46 | return ; 47 | // 如果标记为1(左上箭头),递归进左上格子,递归结束后打印本格字符 48 | if(b[i][j]==1){ 49 | LCS(i-1,j-1,x,b); 50 | // 这里要改,序列的索引应从0起 51 | cout<int: 2 | m,n=len(text1),len(text2) 3 | dp=[[0]*(n+1) for _ in range(m+1)] 4 | for i in range(1,m+1): 5 | for j in range(1,n+1): 6 | if text1[i-1]==text2[j-1]: 7 | dp[i][j]=dp[i-1][j-1]+1 8 | else: 9 | dp[i][j]=max(dp[i-1][j],dp[i][j-1]) 10 | # 输出跟CUMT式先上后左的答案不同的原因在于这个max 11 | return dp[-1][-1]#逆序下标,代表最后一行最后一列,即dp[m][n] 12 | 13 | def main(): 14 | A='abcbdb' 15 | B='acbbabdbb' 16 | print(lcs_length(A,B)) 17 | 18 | if __name__=="__main__": 19 | main() -------------------------------------------------------------------------------- /P57_MaxSum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int MaxSum1(int n,int* a,int &besti,int &bestj){//简单算法 O(n^3) 4 | int sum=0; 5 | for(int i=1;i<=n;i++){ 6 | for(int j=i;j<=n;j++){ 7 | int thisSum=0;// 每次重新计算从i到j的子段和 8 | for(int k=i;k<=j;k++) 9 | thisSum+=a[k]; 10 | if(thisSum>sum){ 11 | sum=thisSum; 12 | besti=i; 13 | bestj=j; 14 | } 15 | } 16 | } 17 | return sum; 18 | } 19 | 20 | int MaxSum2(int n,int* a,int &besti,int &bestj){//改进的简单算法 O(n^2) 21 | int sum=0; 22 | for(int i=1;i<=n;i++){ 23 | int thisSum=0;// 从i到j的子段和=第j个整数+从i到j-1的子段和(上次对j循环得到的子段和) 24 | for(int j=i;j<=n;j++){ 25 | thisSum+=a[j]; 26 | if(thisSum>sum){ 27 | sum=thisSum; 28 | besti=i; 29 | bestj=j; 30 | } 31 | } 32 | } 33 | return sum; 34 | } 35 | 36 | int MaxSubSum(int *a,int left,int right){ 37 | int sum=0; 38 | if(left==right) 39 | return a[left]>0?a[left]:0; 40 | else{ 41 | int middle=(left+right)/2; 42 | int leftSubSum=MaxSubSum(a,left,middle); 43 | int rightSubSum=MaxSubSum(a,middle+1,right); 44 | 45 | int s1=0; 46 | int thisS1=0; 47 | for(int i=middle;i>=left;i--){ 48 | thisS1+=a[i]; 49 | if(thisS1>s1) 50 | s1=thisS1; 51 | } 52 | 53 | int s2=0; 54 | int thisS2=0; 55 | for(int i=middle+1;i<=right;i++){ 56 | thisS2+=a[i]; 57 | if(thisS2>s2) 58 | s2=thisS2; 59 | } 60 | int crossSubSum=s1+s2; 61 | sum=crossSubSum; 62 | if(leftSubSum>sum) 63 | sum=leftSubSum; 64 | if(rightSubSum>sum) 65 | sum=rightSubSum; 66 | } 67 | return sum; 68 | } 69 | 70 | int MaxSum3(int n,int* a){//分治算法 O(nlogn) 71 | return MaxSubSum(a,1,n); 72 | } 73 | 74 | int MaxSum4(int n,int* a){//动态规划算法 O(n) 75 | int sum=0; 76 | int b=0; 77 | // 在变量只从子结构的一种情况转移时可以用一维dp,而且这个状态转移方程只在两个相邻格子之间(b[j-1] b[j])甚至不需要定义数组 78 | // 二维dp也是一样的,状态转移方程只在两个相邻行之间(dp[i][] dp[i-1][])甚至不需要定义m*n的二维数组,这就是许多题解将空间复杂度O(m*n)优化为O(min(m,n))的依据 79 | for(int i=1;i<=n;i++){ 80 | if(i==1) printf("b=["); 81 | printf("%d",b>0 ? b+=a[i] : b=a[i]);// 试了一下赋值语句的返回值,顺便打印过程 82 | if(i!=n) printf(","); 83 | // b>0 ? b+=a[i] : b=a[i]; 84 | // 注意该算法的结果取最大值而不是b[n],要记得打擂保存 85 | if(b>sum) 86 | sum=b; 87 | } 88 | printf("]"); 89 | return sum; 90 | } 91 | 92 | 93 | int main(){ 94 | const int n=6; 95 | int a[n+1]={0,-2,11,-4,13,-5,-2}; 96 | // int besti,bestj; 97 | // int maxSubSum=MaxSum1(n,a,besti,bestj); 98 | // int maxSubSum=MaxSum2(n,a,besti,bestj); 99 | // int maxSubSum=MaxSum3(n,a); 100 | int maxSubSum=MaxSum4(n,a); 101 | // printf("(%d,%d)",besti,bestj); 102 | printf("\n%d",maxSubSum); 103 | return 0; 104 | } -------------------------------------------------------------------------------- /P57_maxsum.py: -------------------------------------------------------------------------------- 1 | n=int(input()) 2 | A=[int(_) for _ in input().split()] 3 | sum=float('-inf') 4 | dp=float('-inf') 5 | for a in A: 6 | dp=max(dp+a,a) 7 | sum=max(sum,dp) 8 | print(sum) -------------------------------------------------------------------------------- /P68_Compress.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int BitLength(int i){ 7 | int k=1; 8 | i/=2; 9 | while(i>0){ 10 | k++; 11 | i/=2; 12 | } 13 | return k; 14 | } 15 | 16 | void Compress(int n,int p[],int s[],int l[],int b[]){ 17 | int Lmax=256,header=11; 18 | s[0]=0; 19 | for(int i=1;i<=n;i++){ 20 | b[i]=BitLength(p[i]); 21 | int bmax=b[i]; 22 | s[i]=s[i-1]+bmax; 23 | l[i]=1; 24 | for(int k=2;k<=i&&k<=Lmax;k++){ 25 | if(bmaxs[i-k]+k*bmax){ 28 | s[i]=s[i-k]+k*bmax; 29 | l[i]=k; 30 | } 31 | } 32 | s[i]+=header; 33 | } 34 | } 35 | 36 | void Traceback(int n,int& i,int s[],int l[]){ 37 | if(n==0) 38 | return ; 39 | Traceback(n-l[n],i,s,l); 40 | s[i++]=n-l[n]; 41 | } 42 | 43 | void Output(int s[],int l[],int b[],int n){ 44 | cout<<"The optimal value is "< 2 | #include 3 | using namespace std; 4 | void MNS(int pi[],int n,int **size){ 5 | // 初始化第一行 6 | for(int j=0;jn-1行按状态转移方程计算 11 | for(int i=2;i1;i--){// 行坐标(上端接线柱) 25 | if(size[i][j]!=size[i-1][j]){ 26 | Net[m++]=i; 27 | j=pi[i]-1; 28 | } 29 | } 30 | // 这里要改,这两句明显只针对第一行,应和前面的n->2行分开 31 | // 第一行的上方格子不能用,只能特判 32 | if(j>=pi[1]) 33 | // 如果下段接线柱pi[2]在pi[1]后面,那么上端接线柱1一定可以加入集合 34 | Net[m++]=1; 35 | } 36 | 37 | bool PrintMatrix(int **m,int r,int c,int pi[]){ 38 | printf(" "); 39 | for (int i=1;i<=c;i++) 40 | printf("%4d",i); 41 | printf("\n"); 42 | printf(" "); 43 | for (int i=1;i<=c;i++) 44 | printf("____"); 45 | printf("\n"); 46 | for (int i=1;i<=r;i++){ 47 | printf("(%2d,%2d) %2d|",i,pi[i],i); 48 | for (int j=1;j<=c;j++) 49 | printf("%4d",m[i][j]); 50 | printf("\n"); 51 | } 52 | printf("\n"); 53 | return true; 54 | } 55 | 56 | 57 | 58 | int main(){ 59 | const int n=10; 60 | int pi[n+1]={0,2,4,7,8,5,6,9,3,10,1}; 61 | // int pi[n+1]={0,8,7,4,2,5,1,9,3,10,6}; 62 | int Net[n]={0}; 63 | int m=0; 64 | int size[n+1][n+1]={0}; 65 | int* psize[n+1]; 66 | for(int i=0;i<(n+1);i++) 67 | psize[i]=size[i]; 68 | MNS(pi,n,psize); 69 | PrintMatrix(psize,n,n,pi); 70 | Traceback(pi,psize,n,Net,m); 71 | printf("{(%d,%d)",Net[m-1],pi[Net[m-1]]); 72 | for(int i=m-2;i>=0;i--) 73 | printf(",(%d,%d)",Net[i],pi[Net[i]]); 74 | printf("}"); 75 | return 0; 76 | } -------------------------------------------------------------------------------- /P75_Knapsack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | template 5 | void Knapsack(Type* v,int* w,int c,int n,Type** m){ 6 | // 初始化第n行 7 | int jMax=min(w[n]-1,c); 8 | for(int j=0;j<=jMax;j++) 9 | m[n][j]=0; 10 | for(int j=w[n];j<=c;j++) 11 | m[n][j]=v[n]; 12 | // 第n-1->2行按状态转移方程计算 13 | for(int i=n-1;i>1;i--){ 14 | jMax=min(w[i]-1,c); 15 | for(int j=0;j<=jMax;j++) 16 | // 装不了的时候,把下一行抄上来,使用其所对应情况的最优解 17 | m[i][j]=m[i+1][j]; 18 | for(int j=w[i];j<=c;j++) 19 | // 能装的时候,考虑一下是不是装了(下一行背包剩余空间最优解+v[i])还没有不装(下方格子最优解)大 20 | m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]); 21 | } 22 | // 第1行只算最后一列,单拎出来 23 | m[1][c]=m[2][c]; 24 | if(c>w[1]) 25 | m[1][c]=max(m[1][c],m[2][c-w[1]]+v[1]); 26 | } 27 | 28 | template 29 | void Traceback(Type** m,int* w,int c,int n,int* x){ 30 | for(int i=1;i 2 | // #include 3 | #include 4 | using namespace std; 5 | // 不直接对数组排序,而是按排序标准对下标排序,这样可以达到同时排序多个数组的效果(保留数组间原本的同下标映射关系) 6 | // int arr[5]= { 4, 1, 3, 6, 2}; 7 | // string arr1[5]={"a1","b1","c1","d1","e1"}; 8 | 9 | // int indices[5]={0,1,2,3,4}; 10 | // sort(indices, indices+5, SortIndices(arr)); 11 | // int indices[5]={1,4,2,0,3}; //排序完应该是这样的 12 | 13 | // arr[indices[i]]与arr1[indices[i]]仍有映射关系 14 | 15 | class SortIndices{ 16 | private: 17 | int* mparr; 18 | public: 19 | SortIndices(int* parr) 20 | :mparr(parr) 21 | {} 22 | bool operator()(int i,int j)const{ 23 | return mparr[i]