├── .github └── workflows │ └── main.yml ├── README.md ├── docs ├── 1000 A+B=C.md ├── 1001 统计数字个数.md ├── 1002 找第2小数.md ├── 1003 冒泡排序.md ├── 1004 归并排序.md ├── 1005 快速排序.md ├── 1006 堆排序.md ├── 1007 最大乘积.md ├── 1008 拦截导弹2.md ├── 1009 拦截导弹1.md ├── 1010 二分搜素.md ├── 1011 最近点对.md ├── 1012 寻找凸包.md ├── 1013 逆序对.md ├── 1014 最大子数组和.md ├── 1015 天机轮廓.md ├── 1016 两元素和.md ├── 1017 电路布线.md ├── 1018 01背包问题2.md ├── 1019 01背包问题1.md ├── 1020 矩阵连乘.md ├── 1021 钢条切割.md ├── 1022 最长公共子序列.md ├── 1025 最长非降子序列.md ├── 1026 插入乘号.md ├── 1027 带权活动选择.md ├── 1039 拓扑排序.md ├── 1040 搜索二位矩阵.md ├── 1041 寻找两个正序数组的中位数.md ├── 1042 最低票价.md ├── 1043 鸡蛋掉落.md └── index.md └── mkdocs.yml /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the workflow will run 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the main branch 8 | push: 9 | branches: [ main ] 10 | pull_request: 11 | branches: [ main ] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | build: 20 | # The type of runner that the job will run on 21 | runs-on: ubuntu-latest 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v2 27 | 28 | - uses: actions/setup-python@v2 29 | with: 30 | python-version: 3.x 31 | - run: pip install mkdocs 32 | - run: pip install mkdocs-material 33 | - run: mkdocs gh-deploy --force 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 东南大学算法设计与分析课程OJ答案 2 | --- 3 | 在线入口:https://zpengc.github.io/seu_monash_algorithm-design-and-analysis/ 4 | 5 | --- 6 | 7 | ## 参考资料 8 | - **Weight Interval Scheduling** https://courses.cs.washington.edu/courses/cse521/13wi/slides/06dp-sched.pdf 9 | 10 | - **算法导论** https://edutechlearners.com/download/Introduction_to_algorithms-3rd%20Edition.pdf 11 | 12 | - **CMSC451课程** http://www.cs.umd.edu/~jkatz/451/f21/lectures.html 13 | 14 | - **Cloest Point Pair** 15 | - https://ocw.tudelft.nl/wp-content/uploads/Algoritmiek_Closest_Pair_of_Points.pdf 16 | - http://people.csail.mit.edu/indyk/6.838-old/handouts/lec17.pdf 17 | 18 | - **摊还分析**https://sites.cs.ucsb.edu/~suri/cs130a/Amortized.pdf 19 | 20 | - **black and white color problem of tree nodes** 21 | 22 | - https://web.stanford.edu/class/cs97si/04-dynamic-programming.pdf 23 | - https://blog.csdn.net/weixin_30672295/article/details/94898224 24 | 25 | - 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /docs/1000 A+B=C.md: -------------------------------------------------------------------------------- 1 | ``` 2 | #include 3 | using namespace std; 4 | int main() { 5 | int n, a, b; 6 | cin >> n; 7 | for(int i=0; i> a >> b; 9 | cout << a + b << endl; 10 | } 11 | return 0; 12 | } 13 | ``` -------------------------------------------------------------------------------- /docs/1001 统计数字个数.md: -------------------------------------------------------------------------------- 1 | ``` 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() 8 | { 9 | int n; 10 | cin>>n; 11 | string str; 12 | getline(cin, str); 13 | for(int i=0;i='0' && str[j]<='9') 20 | { 21 | num++; 22 | } 23 | } 24 | cout< 3 | #include 4 | using namespace std; 5 | 6 | int f(int a[], int size) 7 | { 8 | int first, second; 9 | if (size < 2) 10 | { 11 | return 0; 12 | } 13 | first = second = INT_MAX; 14 | for(int i=0;i>n; 34 | for(int i=0;i>size; 38 | int a[size]; 39 | for(int j=0; j> a[j]; 41 | cout< 3 | using namespace std; 4 | 5 | void bubble_sort_one_iter(int a[], int size) 6 | { 7 | for(int i=0;ia[i+1]) 10 | { 11 | swap(a[i], a[i+1]); 12 | } 13 | } 14 | for(int i=0;i>n; 25 | for(int i=0;i>size; 29 | int a[size]; 30 | for(int i=0;i>a[i]; 33 | } 34 | bubble_sort_one_iter(a, size); 35 | } 36 | return 0; 37 | } 38 | ``` -------------------------------------------------------------------------------- /docs/1004 归并排序.md: -------------------------------------------------------------------------------- 1 | ``` 2 | #include 3 | using namespace std; 4 | 5 | int temp[1000]; 6 | int res[1000]; 7 | 8 | void merge(int a[], int low, int middle, int high){ 9 | 10 | int i=low,k=low,j=middle+1; 11 | while(i <= middle && j <= high){ 12 | if(a[i]<=a[j]) 13 | temp[k++]=a[i++]; 14 | else temp[k++]=a[j++]; 15 | } 16 | while(i<=middle) 17 | temp[k++]=a[i++]; 18 | while(j<=high) 19 | temp[k++]=a[j++]; 20 | for(k=low;k<=high;k++) 21 | a[k] = temp[k]; 22 | return; 23 | 24 | } 25 | 26 | void merge_sort(int a[], int low, int high, int level) 27 | { 28 | if (low >= high) 29 | { 30 | return; 31 | } 32 | int middle = (low+high)/2; 33 | merge_sort(a, low, middle, level+1); 34 | merge_sort(a, middle+1, high, level+1); 35 | merge(a, low, middle, high); 36 | if(level==3) 37 | { 38 | for(int i=low;i<=high;i++) 39 | { 40 | res[i] = a[i]; 41 | } 42 | } 43 | } 44 | 45 | void print(int a[], int size) 46 | { 47 | for(int i=0;i>n; 58 | for(int i=0;i>size; 62 | int a[size]; 63 | for(int i=0;i>a[i]; 66 | } 67 | merge_sort(a, 0, size-1, 1); 68 | print(res, size); 69 | } 70 | return 0; 71 | } 72 | 73 | ``` -------------------------------------------------------------------------------- /docs/1005 快速排序.md: -------------------------------------------------------------------------------- 1 | ``` 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int f(int a[], int size) 7 | { 8 | int first, second; 9 | if (size < 2) 10 | { 11 | return 0; 12 | } 13 | first = second = INT_MAX; 14 | for(int i=0;i>n; 34 | for(int i=0;i>size; 38 | int a[size]; 39 | for(int j=0; j> a[j]; 41 | cout< 3 | using namespace std; 4 | 5 | void heapify(int a[], int size, int idx) 6 | { 7 | int smallest = idx; 8 | int left = idx*2+1; 9 | int right = idx*2+2; 10 | // 优先向左子树调整 11 | if(left=0;i--) 32 | { 33 | heapify(a, size, i); 34 | } 35 | } 36 | 37 | void print(int a[], int size) 38 | { 39 | for(int i=0;i>n; 50 | for(int i=0;i>size; 54 | int a[size]; 55 | for(int i=0;i>a[i]; 58 | } 59 | heap_sort(a, size); 60 | print(a, size); 61 | } 62 | return 0; 63 | } 64 | 65 | ``` -------------------------------------------------------------------------------- /docs/1007 最大乘积.md: -------------------------------------------------------------------------------- 1 | ``` 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | //返回v[start]~v[end]这些数字所表示的数值 9 | long nums(int v[],int start,int end){ 10 | long num=v[start]; 11 | for(int k=start+1;k<=end;k++){ 12 | num = num*10+v[k]; 13 | } 14 | return num; 15 | } 16 | 17 | long MaxMult(int v[], int bits,int k){ 18 | // 原数字0~bits-1位中加入k个乘号所得表达式的最大值 19 | long dp[bits][k+1]; 20 | memset(dp,0,sizeof(dp)); 21 | for(int i=0; i> n; 41 | for(int i=0; i>bits>>k; 45 | string s; 46 | cin >> s; 47 | int v[bits]; 48 | for(int j=0;j 3 | using namespace std; 4 | 5 | // Longest Decreasing Subsequence problem 6 | int LDS(int a[], int num) 7 | { 8 | int lds[num]; 9 | int max = 0; 10 | for (int i = 0; i < num; i++) 11 | { 12 | lds[i] = 1; 13 | } 14 | for (int i = 1; i < num; i++) 15 | { 16 | for (int j = 0; j < i; j++) 17 | { 18 | if (a[i] < a[j] && lds[i] < lds[j] + 1) 19 | { 20 | lds[i] = lds[j] + 1; 21 | } 22 | } 23 | } 24 | for (int i = 0; i < num; i++) 25 | { 26 | if (max < lds[i]) 27 | { 28 | max = lds[i]; 29 | } 30 | } 31 | return max; 32 | } 33 | 34 | int greedy(int a[], int num) 35 | { 36 | // height[i]表示第i个系统能够发射的最大高度 37 | int height[num]; 38 | // count用来计数 39 | int count=0,min_idx=0; 40 | 41 | height[0] = a[0]; 42 | for(int i=1;iheight[count]){ 45 | height[++count]=a[i]; 46 | } 47 | else{ 48 | min_idx=count; 49 | for(int j=count;j>=0;j--) 50 | { 51 | //所有系统中发射高度最矮的那套来拦截 52 | if(height[j]=a[i]) 53 | { 54 | min_idx=j; 55 | } 56 | } 57 | height[min_idx]=a[i]; 58 | } 59 | } 60 | return count+1; 61 | } 62 | 63 | int main() { 64 | int n; 65 | cin >> n; 66 | for(int i=0; i>num; 69 | int a[num]; 70 | for(int j=0;j>a[j]; 73 | } 74 | cout< 3 | using namespace std; 4 | 5 | // Longest Decreasing Subsequence problem 6 | int LDS(int a[], int num) 7 | { 8 | int lds[num]; 9 | int max = 0; 10 | for (int i = 0; i < num; i++) 11 | { 12 | lds[i] = 1; 13 | } 14 | for (int i = 1; i < num; i++) 15 | { 16 | for (int j = 0; j < i; j++) 17 | { 18 | if (a[i] < a[j] && lds[i] < lds[j] + 1) 19 | { 20 | lds[i] = lds[j] + 1; 21 | } 22 | } 23 | } 24 | for (int i = 0; i < num; i++) 25 | { 26 | if (max < lds[i]) 27 | { 28 | max = lds[i]; 29 | } 30 | } 31 | return max; 32 | } 33 | 34 | 35 | int main() { 36 | int n; 37 | cin >> n; 38 | for(int i=0; i>num; 41 | int a[num]; 42 | for(int j=0;j>a[j]; 45 | } 46 | cout< 3 | using namespace std; 4 | 5 | void binary_search(int a[], int low, int high, int target) 6 | { 7 | int temp = a[(low+high)/2]; 8 | while(low<=high) 9 | { 10 | int mid = (low+high)/2; 11 | if(a[mid]==target) 12 | { 13 | cout<<"success, father is "<target) 17 | { 18 | high = mid-1; 19 | temp = a[mid]; 20 | } 21 | else 22 | { 23 | low = mid+1; 24 | temp = a[mid]; 25 | } 26 | } 27 | cout<<"not found, father is "<> n; 33 | for(int i=0; i>size; 36 | int target; 37 | cin>>target; 38 | int a[size]; 39 | for(int j=0;j>a[j]; 42 | } 43 | binary_search(a, 0, size-1, target); 44 | } 45 | return 0; 46 | } 47 | ``` -------------------------------------------------------------------------------- /docs/1011 最近点对.md: -------------------------------------------------------------------------------- 1 | ``` 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | struct Point 9 | { 10 | int x; 11 | int y; 12 | }; 13 | 14 | 15 | // http://www.cplusplus.com/reference/cstdlib/qsort/ qsort函数需要compar函数原型 16 | int compareX(const void* a, const void* b) 17 | { 18 | Point *p1 = (Point *)a, *p2 = (Point *)b; 19 | return (p1->x != p2->x) ? (p1->x - p2->x) : (p1->y - p2->y); 20 | } 21 | 22 | int compareY(const void* a, const void* b) 23 | { 24 | Point *p1 = (Point *)a, *p2 = (Point *)b; 25 | return (p1->y != p2->y) ? (p1->y - p2->y) : (p1->x - p2->x); 26 | } 27 | 28 | 29 | float dist(Point p1, Point p2) 30 | { 31 | // 乘以1.0防止int类型溢出 32 | float x = sqrt( 1.0*(p1.x - p2.x)*1.0*(p1.x - p2.x) + 1.0*(p1.y - p2.y)*1.0*(p1.y - p2.y)); 33 | return x; 34 | } 35 | 36 | float bruteForce(Point P[], int n) 37 | { 38 | float min = FLT_MAX; 39 | for (int i = 0; i < n; ++i) 40 | for (int j = i+1; j < n; ++j) 41 | if (dist(P[i], P[j]) < min) 42 | min = dist(P[i], P[j]); 43 | return min; 44 | } 45 | 46 | float min(float x, float y) 47 | { 48 | return (x < y)? x : y; 49 | } 50 | 51 | 52 | float stripClosest(Point strip[], int size, float d) 53 | { 54 | float min = d; 55 | 56 | for (int i = 0; i < size; ++i) 57 | for (int j = i+1; j < size && (strip[j].y - strip[i].y) < min; ++j) 58 | if (dist(strip[i],strip[j]) < min) 59 | min = dist(strip[i], strip[j]); 60 | 61 | return min; 62 | } 63 | 64 | float closestUtil(Point Px[], Point Py[], int n) 65 | { 66 | if (n <= 3) 67 | return bruteForce(Px, n); 68 | 69 | int mid = n/2; 70 | Point midPoint = Px[mid]; 71 | 72 | 73 | Point Pyl[mid]; 74 | Point Pyr[n-mid]; 75 | int li = 0, ri = 0; 76 | for (int i = 0; i < n; i++) 77 | { 78 | if ((Py[i].x < midPoint.x || (Py[i].x == midPoint.x && Py[i].y < midPoint.y)) && li>n; 120 | for(int i=0;i>size; 124 | Point P[size]; 125 | for(int i=0;i>p.x; 129 | cin>>p.y; 130 | P[i] = p; 131 | } 132 | 133 | cout< 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct Point 8 | { 9 | int x, y; 10 | }; 11 | 12 | Point p0; 13 | 14 | // A utility function to find next to top in a stack 15 | Point nextToTop(stack &S) 16 | { 17 | Point p = S.top(); 18 | S.pop(); 19 | Point res = S.top(); 20 | S.push(p); 21 | return res; 22 | } 23 | 24 | // A utility function to swap two points 25 | void swap(Point &p1, Point &p2) 26 | { 27 | Point temp = p1; 28 | p1 = p2; 29 | p2 = temp; 30 | } 31 | 32 | // A utility function to return square of distance 33 | // between p1 and p2 34 | int distSq(Point p1, Point p2) 35 | { 36 | return (p1.x - p2.x)*(p1.x - p2.x) + 37 | (p1.y - p2.y)*(p1.y - p2.y); 38 | } 39 | 40 | // To find orientation of ordered triplet (p, q, r). 41 | // The function returns following values 42 | // 0 --> p, q and r are collinear 43 | // 1 --> Clockwise 44 | // 2 --> Counterclockwise 45 | int orientation(Point p, Point q, Point r) 46 | { 47 | int val = (q.y - p.y) * (r.x - q.x) - 48 | (q.x - p.x) * (r.y - q.y); 49 | 50 | if (val == 0) return 0; // collinear 51 | return (val > 0)? 1: 2; // clock or counterclock wise 52 | } 53 | 54 | // A function used by library function qsort() to sort an array of 55 | // points with respect to the first point 56 | int compare(const void *vp1, const void *vp2) 57 | { 58 | Point *p1 = (Point *)vp1; 59 | Point *p2 = (Point *)vp2; 60 | 61 | // Find orientation 62 | int o = orientation(p0, *p1, *p2); 63 | if (o == 0) 64 | return (distSq(p0, *p2) >= distSq(p0, *p1))? -1 : 1; 65 | 66 | return (o == 2)? -1: 1; 67 | } 68 | 69 | // Prints convex hull of a set of n points. 70 | void convexHull(Point points[], int n ,int id) 71 | { 72 | // Find the bottommost point 73 | int ymin = points[0].y, min = 0; 74 | for (int i = 1; i < n; i++) 75 | { 76 | int y = points[i].y; 77 | 78 | // Pick the bottom-most or chose the left 79 | // most point in case of tie 80 | if ((y < ymin) || (ymin == y && 81 | points[i].x < points[min].x)) 82 | ymin = points[i].y, min = i; 83 | } 84 | 85 | // Place the bottom-most point at first position 86 | swap(points[0], points[min]); 87 | 88 | // Sort n-1 points with respect to the first point. 89 | // A point p1 comes before p2 in sorted output if p2 90 | // has larger polar angle (in counterclockwise 91 | // direction) than p1 92 | p0 = points[0]; 93 | qsort(&points[1], n-1, sizeof(Point), compare); 94 | 95 | // If two or more points make same angle with p0, 96 | // Remove all but the one that is farthest from p0 97 | // Remember that, in above sorting, our criteria was 98 | // to keep the farthest point at the end when more than 99 | // one points have same angle. 100 | int m = 1; // Initialize size of modified array 101 | for (int i=1; i S; 121 | S.push(points[0]); 122 | S.push(points[1]); 123 | S.push(points[2]); 124 | 125 | // Process remaining n-3 points 126 | for (int i = 3; i < m; i++) 127 | { 128 | // Keep removing top while the angle formed by 129 | // points next-to-top, top, and points[i] makes 130 | // a non-left turn 131 | while (S.size()>1 && orientation(nextToTop(S), S.top(), points[i]) != 2) 132 | S.pop(); 133 | S.push(points[i]); 134 | } 135 | 136 | // Now stack has the output points, print contents of stack 137 | cout<<"case "< ss; 139 | while (!S.empty()) 140 | { 141 | Point p = S.top(); 142 | ss.push(p); 143 | S.pop(); 144 | } 145 | while (!ss.empty()) 146 | { 147 | Point p = ss.top(); 148 | cout << p.x << " " << p.y << endl; 149 | ss.pop(); 150 | } 151 | } 152 | 153 | int main() 154 | { 155 | int n; 156 | cin>>n; 157 | for(int i=0;i>size; 161 | Point p[size]; 162 | for(int j=0;j>p[j].x; 165 | cin>>p[j].y; 166 | } 167 | convexHull(p, size, i); 168 | } 169 | return 0; 170 | } 171 | ``` -------------------------------------------------------------------------------- /docs/1013 逆序对.md: -------------------------------------------------------------------------------- 1 | ``` 2 | #include 3 | using namespace std; 4 | 5 | int merge(int arr[], int temp[], int left, int mid, 6 | int right) 7 | { 8 | int i, j, k; 9 | int inv_count = 0; 10 | 11 | i = left; /* i is index for left subarray*/ 12 | j = mid; /* j is index for right subarray*/ 13 | k = left; /* k is index for resultant merged subarray*/ 14 | while ((i <= mid - 1) && (j <= right)) { 15 | if (arr[i] <= arr[j]) { 16 | temp[k++] = arr[i++]; 17 | } 18 | else { 19 | temp[k++] = arr[j++]; 20 | 21 | inv_count = inv_count + (mid - i); 22 | } 23 | } 24 | 25 | while (i <= mid - 1) 26 | temp[k++] = arr[i++]; 27 | 28 | while (j <= right) 29 | temp[k++] = arr[j++]; 30 | 31 | for (i = left; i <= right; i++) 32 | arr[i] = temp[i]; 33 | 34 | return inv_count; 35 | } 36 | 37 | int _mergeSort(int arr[], int temp[], int left, int right) 38 | { 39 | int inv_count = 0; 40 | if (right > left) { 41 | int mid = (right + left) / 2; 42 | 43 | inv_count += _mergeSort(arr, temp, left, mid); 44 | inv_count += _mergeSort(arr, temp, mid + 1, right); 45 | 46 | inv_count += merge(arr, temp, left, mid + 1, right); 47 | } 48 | return inv_count; 49 | } 50 | 51 | int mergeSort(int arr[], int array_size) 52 | { 53 | int temp[array_size]; 54 | return _mergeSort(arr, temp, 0, array_size - 1); 55 | } 56 | 57 | int main() 58 | { 59 | int n; 60 | cin>>n; 61 | for(int i=0;i>size; 65 | int arr[size]; 66 | for(int j=0;j>arr[j]; 69 | } 70 | cout< 3 | #include 4 | using namespace std; 5 | 6 | int func(int a[], int size) 7 | { 8 | int res = INT_MIN; 9 | int max_end_here = 0; 10 | for(int i=0;i res) 14 | { 15 | res = max_end_here; 16 | } 17 | if(max_end_here < 0) 18 | { 19 | max_end_here = 0; 20 | } 21 | } 22 | return res; 23 | } 24 | 25 | int main() 26 | { 27 | int n; 28 | cin>>n; 29 | for(int i=0;i>size; 33 | int arr[size]; 34 | for(int j=0;j>arr[j]; 37 | } 38 | cout< 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | vector> getSkyline(vector>& buildings) { 10 | // use walls to record buildings; left wall is an insertion event, and right wall is a deletion event 11 | vector> walls, ans; // first: x, second: height 12 | for (auto b : buildings) { 13 | // push in left / right walls 14 | // let left wall has negative height to ensure left wall goes to multiset first if with same 'x' as right wall 15 | walls.push_back(make_pair(b[0], -b[2])); 16 | walls.push_back(make_pair(b[1], b[2])); 17 | } 18 | sort(walls.begin(), walls.end()); // sort walls 19 | 20 | multiset leftWallHeights = {0}; // keep left wall heights sorted; dummy '0' for convenience 21 | int top = 0; // current max height among leftWallHeights 22 | for (auto w : walls) { 23 | if (w.second < 0) { // it's a left wall, insert the height 24 | leftWallHeights.insert(-w.second); 25 | } else { // it's a right wall, delete the height 26 | leftWallHeights.erase(leftWallHeights.find(w.second)); 27 | } 28 | 29 | if (*leftWallHeights.rbegin() != top) { // mark a skyline point if top changes 30 | ans.push_back(make_pair(w.first, top = *leftWallHeights.rbegin())); 31 | } 32 | } 33 | 34 | return ans; 35 | } 36 | 37 | void func(vector> buildings) 38 | { 39 | vector> ans = getSkyline(buildings); 40 | for (auto it : ans) { 41 | cout<>n; 50 | vector> buildings; 51 | for(int i=0;i building(3); 54 | for(int j=0;j>building[j]; 57 | } 58 | buildings.push_back(building); 59 | } 60 | func(buildings); 61 | return 0; 62 | } 63 | ``` -------------------------------------------------------------------------------- /docs/1016 两元素和.md: -------------------------------------------------------------------------------- 1 | ``` 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | 7 | 8 | bool func(int arr[], int size, int target) 9 | { 10 | unordered_set s; 11 | for(int i=0;i>n; 30 | for(int i=0;i>size; 34 | cin>>target; 35 | int arr[size]; 36 | for(int j=0;j>arr[j]; 39 | } 40 | if(func(arr, size, target)) 41 | { 42 | cout<<"yes"< 3 | using namespace std; 4 | 5 | 6 | int merge(int array[], int const left, int const mid, int const right) 7 | { 8 | int s1 = mid - left + 1; 9 | int s2 = right - mid; 10 | 11 | int *leftArray = new int[s1], 12 | *rightArray = new int[s2]; 13 | 14 | for (int i = 0; i < s1; i++) 15 | leftArray[i] = array[left + i]; 16 | for (int j = 0; j < s2; j++) 17 | rightArray[j] = array[mid + 1 + j]; 18 | 19 | int indexOfSubArrayOne = 0, indexOfSubArrayTwo = 0; 20 | int indexOfMergedArray = left; 21 | int sum=0; 22 | while (indexOfSubArrayOne < s1 && indexOfSubArrayTwo < s2) { 23 | if (leftArray[indexOfSubArrayOne] <= rightArray[indexOfSubArrayTwo]) { 24 | array[indexOfMergedArray] = leftArray[indexOfSubArrayOne]; 25 | indexOfSubArrayOne++; 26 | sum+=indexOfSubArrayTwo; 27 | } 28 | else { 29 | array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo]; 30 | indexOfSubArrayTwo++; 31 | } 32 | indexOfMergedArray++; 33 | } 34 | while (indexOfSubArrayOne < s1) { 35 | array[indexOfMergedArray] = leftArray[indexOfSubArrayOne]; 36 | indexOfSubArrayOne++; 37 | indexOfMergedArray++; 38 | sum+=indexOfSubArrayTwo; 39 | } 40 | while (indexOfSubArrayTwo < s2) { 41 | array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo]; 42 | indexOfSubArrayTwo++; 43 | indexOfMergedArray++; 44 | } 45 | return sum; 46 | } 47 | 48 | int mergeSort(int array[], int begin, int end) 49 | { 50 | if (begin >= end) 51 | return 0; 52 | int sum=0; 53 | auto mid = (begin + end) / 2; 54 | sum+=mergeSort(array, begin, mid); 55 | sum+=mergeSort(array, mid + 1, end); 56 | sum+=merge(array, begin, mid, end); 57 | return sum; 58 | } 59 | 60 | 61 | int main() 62 | { 63 | int n; 64 | cin>>n; 65 | for(int i=0;i>size; 69 | int arr[size]; 70 | for(int j=0;j>arr[j]; 73 | } 74 | cout< 3 | #include 4 | using namespace std; 5 | 6 | int func(int weight[], int profit[], int capacity, int n_gem) 7 | { 8 | vector> dp(n_gem+1, vector(capacity+1, -1)); 9 | for(int i=0;i<=n_gem;i++) 10 | { 11 | dp[i][0] = 0; 12 | } 13 | 14 | for (int i=1;i<=n_gem;i++) 15 | { 16 | for (int j=capacity;j>=1;j--) 17 | { 18 | // weight, profit数组下标从0开始,所以i-1 19 | int curr_weight = weight[i - 1]; 20 | int curr_profit = profit[i - 1]; 21 | if (j >= curr_weight && dp[i - 1][j - curr_weight] != -1) 22 | { 23 | dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - curr_weight] + curr_profit); 24 | } 25 | else 26 | { 27 | dp[i][j] = dp[i - 1][j]; 28 | } 29 | } 30 | } 31 | if(dp[n_gem][capacity] == -1) 32 | { 33 | return 0; 34 | } 35 | return dp[n_gem][capacity]; 36 | } 37 | 38 | int main() { 39 | // 测试次数 40 | int n_test; 41 | cin>>n_test; 42 | for(int i=0;i>n_gem; 47 | // 背包容量 48 | int bag_capacity; 49 | cin>>bag_capacity; 50 | int weight[n_gem]; 51 | int profit[n_gem]; 52 | for(int i=0;i>weight_gem; 57 | // 宝石价值 58 | int profit_gem; 59 | cin>>profit_gem; 60 | weight[i] = weight_gem; 61 | profit[i] = profit_gem; 62 | } 63 | cout< 3 | #include 4 | using namespace std; 5 | 6 | int func(int weight[], int profit[], int capacity, int n_gem) 7 | { 8 | vector> dp(n_gem + 1, vector(capacity + 1)); 9 | for(int i=0;i<=n_gem;i++) 10 | { 11 | dp[i][0] = 0; 12 | } 13 | for(int i=0;i<=capacity;i++) 14 | { 15 | dp[0][i] = 0; 16 | } 17 | for(int i = 1; i <= n_gem; i++) 18 | { 19 | for(int j = 1; j <= capacity; j++) 20 | { 21 | // 容量允许,可以装入物品 22 | if(j >= weight[i-1]) 23 | { 24 | // 分为两种情况,装入物品和不装入物品 25 | dp[i][j] = max(profit[i - 1] + dp[i - 1][j - weight[i - 1]], dp[i - 1][j]); 26 | } 27 | // 容量不足,不装入该物品 28 | else 29 | { 30 | dp[i][j] = dp[i-1][j]; 31 | } 32 | } 33 | } 34 | return dp[n_gem][capacity]; 35 | } 36 | 37 | int main() { 38 | // 测试次数 39 | int n_test; 40 | cin>>n_test; 41 | for(int i=0;i>n_gem; 46 | // 背包容量 47 | int bag_capacity; 48 | cin>>bag_capacity; 49 | int weight[n_gem]; 50 | int profit[n_gem]; 51 | for(int i=0;i>weight_gem; 56 | // 宝石价值 57 | int profit_gem; 58 | cin>>profit_gem; 59 | weight[i] = weight_gem; 60 | profit[i] = profit_gem; 61 | } 62 | cout< 3 | #include 4 | using namespace std; 5 | 6 | // 数组长度为n,矩阵个数为n-1 7 | int min_cost(int p[], int n) 8 | { 9 | // m[i,j]表示矩阵matrix[i] matrix[i+1] ... matrix[j-1] matrix[j]的最小乘法代价 10 | int m[n][n]; 11 | int i, j, k, L, q; 12 | 13 | // 一个矩阵,不存在最小乘法代价,为0 14 | // 索引从1到n-1,表示矩阵1-矩阵n-1 15 | for (i=1; i>n_test; 49 | for(int i=0;i>n_matrix; 54 | // 存储每个矩阵的行数和列数,前一个矩阵的列数和后一个矩阵的行数重复,只存储1个,因此大小为2*n_matrix-(n_matrix-1) 55 | int chain[n_matrix+1]; 56 | for(int i=0;i>row; 61 | int col; 62 | cin>>col; 63 | if(i==0) 64 | { 65 | chain[i] = row; 66 | chain[i+1] = col; 67 | } 68 | else 69 | { 70 | chain[i+1] = col; 71 | } 72 | } 73 | cout< 3 | #include 4 | using namespace std; 5 | 6 | // 无限背包问题,钢材相当于背包,每个售卖的小段钢材相当于物品,假设每种售卖的小段钢材是没有数量限制的 7 | // dp数组申请为1维数组,2维数组显示内存不足错误 8 | int cut_rod(int prices[], int sizes[], int capacity, int n) 9 | { 10 | // 局部变量赋值为0,否则系统赋随机值 11 | int dp[capacity+1] = {0,}; 12 | // 背包容量为0 13 | dp[0] = 0; 14 | // 从小到大遍历所有背包容量 15 | for(int i=1;i<=capacity;i++) 16 | { 17 | // 遍历所有物品 18 | for(int j=0;j>n_test; 34 | for(int i=0;i>capacity; 39 | // 价目表价格种类数 40 | int n_types; 41 | cin>>n_types; 42 | int prices[n_types]; 43 | int sizes[n_types]; 44 | for(int j=0;j>sizes[j]; 47 | cin>>prices[j]; 48 | } 49 | cout< 3 | #include 4 | using namespace std; 5 | 6 | //最长公共序列和最长公共子串不是一个问题 7 | 8 | // longest common sequence 9 | int lcs(string s, string t, int m, int n) 10 | { 11 | // dp[i][j]表示长度为i的字符串和长度为j的字符串的lcs 12 | int dp[m+1][n+1] = {0,}; 13 | for(int i=0;i<=m;i++) 14 | { 15 | for(int j=0;j<=n;j++) 16 | { 17 | // 任何一个字符串长度为0,lcs结果为0 18 | if(i==0 || j==0) 19 | { 20 | dp[i][j] = 0; 21 | } 22 | // 两个字符串最后一个字符相同 23 | else if(s[i-1] == t[j-1]) 24 | { 25 | // 状态转移方程1 26 | dp[i][j] = dp[i-1][j-1] + 1; 27 | } 28 | else 29 | { 30 | // 状态转移方程2 31 | dp[i][j] = max(dp[i-1][j], dp[i][j-1]); 32 | } 33 | } 34 | } 35 | return dp[m][n]; 36 | } 37 | 38 | 39 | int main() { 40 | // 测试次数 41 | int n_test; 42 | cin>>n_test; 43 | for(int i=0;i>s1; 48 | cin>>s2; 49 | cout< 3 | #include 4 | using namespace std; 5 | 6 | int func(int arr[], int n) 7 | { 8 | int dp[n] = {1,}; 9 | for(int i=0;i= arr[j]) 18 | dp[i] = max(dp[i], dp[j] + 1); 19 | } 20 | 21 | int ans = INT_MIN; 22 | for(int i=0;i ans) 25 | { 26 | ans = dp[i]; 27 | } 28 | } 29 | return ans; 30 | } 31 | 32 | int main() { 33 | // 测试次数 34 | int n_test; 35 | cin>>n_test; 36 | for(int i=0;i>num; 40 | int arr[num]; 41 | for(int j=0;j>arr[j]; 44 | } 45 | cout< 3 | using namespace std; 4 | 5 | 6 | long long func(int arr[],int n, int k) { 7 | // dp[i][j]表示在第1到第i个数里面插入j个乘号得到的最大值 8 | long long dp[n+1][n+1]; 9 | long long sum[n+1]; 10 | sum[0]=0; 11 | // 存储累加和 12 | for(int i=1; i<=n;i++) 13 | { 14 | sum[i] = sum[i-1] + arr[i]; 15 | } 16 | for(int i=1; i<=n;i++) { 17 | dp[i][0] = sum[i]; 18 | } 19 | for(int i=2;i<=n;++i) 20 | for(int j=1;j> n_test; 45 | for(int i=0; i>n; 49 | cin>>k; 50 | int arr[n+1]; 51 | for(int j=1;j<=n;j++){ 52 | cin >> arr[j]; 53 | } 54 | cout< 3 | #include 4 | using namespace std; 5 | 6 | struct activity 7 | { 8 | int start_time; 9 | int finish_time; 10 | int weight; 11 | }; 12 | 13 | bool compare(activity a1, activity a2) 14 | { 15 | return (a1.finish_time != a2.finish_time) ? (a1.finish_time < a2.finish_time) : (a1.start_time < a2.start_time); 16 | } 17 | 18 | 19 | int get_last_activity(activity arr[], int idx) 20 | { 21 | // arr为根据结束时间排序后的数组 22 | // 从后往前找 23 | for(int i=idx-1;i>=0;i--) 24 | { 25 | if(arr[i].finish_time <= arr[idx].start_time) 26 | { 27 | return i; 28 | } 29 | } 30 | return -1; 31 | } 32 | 33 | int choose(activity arr[], int n) 34 | { 35 | int dp[n+1]; 36 | dp[1] = arr[0].weight; 37 | for(int i=2;i<=n;i++) 38 | { 39 | int sum = arr[i-1].weight; 40 | int idx = get_last_activity(arr, i-1); 41 | if(idx!=-1) 42 | { 43 | sum += dp[idx+1]; 44 | } 45 | dp[i] = max(sum, dp[i-1]); 46 | } 47 | return dp[n]; 48 | } 49 | 50 | int main() { 51 | // 测试次数 52 | int n_test; 53 | cin>>n_test; 54 | for(int i=0;i>n_activity; 59 | activity arr[n_activity]; 60 | for(int j=0;j>temp.start_time; 64 | cin>>temp.finish_time; 65 | cin>>temp.weight; 66 | arr[j] = temp; 67 | } 68 | sort(arr, arr+n_activity, compare); 69 | cout< 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | 8 | int main() 9 | { 10 | int n_test; 11 | cin>>n_test; 12 | for(int i=0;i>n_vertex; 17 | cin>>n_edge; 18 | int in_degree[n_vertex+1] = {0,}; 19 | vector> adj(n_vertex+1, vector(n_vertex+1, 0)); 20 | vector ans; 21 | queue zero_degree; 22 | for(int j=0;jv 25 | int u; 26 | int v; 27 | cin>>u; 28 | cin>>v; 29 | adj[u].push_back(v); 30 | in_degree[v]++; 31 | } 32 | for(int k=1;k<=n_vertex;k++) 33 | { 34 | if(in_degree[k]==0) 35 | { 36 | zero_degree.push(k); 37 | } 38 | } 39 | int num = 0; 40 | while(!zero_degree.empty()) 41 | { 42 | int vertice = zero_degree.front(); 43 | zero_degree.pop(); 44 | ans.push_back(vertice); 45 | for(int i=0;i 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // 思想就是和矩阵右上角元素比较,不断缩小范围 8 | bool search(vector> matrix, int row, int col, int target) 9 | { 10 | if(row==0 || col==0) 11 | { 12 | return false; 13 | } 14 | int i = 0; 15 | int j = col-1; 16 | while(i=0) 17 | { 18 | if(target == matrix[i][j]) 19 | { 20 | return true; 21 | } 22 | else if(target < matrix[i][j]) 23 | { 24 | j--; 25 | } 26 | else 27 | { 28 | i++; 29 | } 30 | } 31 | return false; 32 | } 33 | 34 | int main() 35 | { 36 | int n_test; 37 | cin>>n_test; 38 | for(int i=0;i>row; 44 | cin>>col; 45 | cin>>target; 46 | vector> matrix(row, vector(col)); 47 | for(int i=0;i>matrix[i][j]; 52 | } 53 | } 54 | cout< 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // leetcode 4. 8 | // https://leetcode.com/problems/median-of-two-sorted-arrays/ 9 | 10 | float func(int arr1[], int arr2[], int len_1, int len_2) 11 | { 12 | int arr[len_1+len_2]; 13 | int p = 0; 14 | int q = 0; 15 | int idx = 0; 16 | while(p>n_test; 49 | for(int i=0;i>len_1; 54 | cin>>len_2; 55 | int arr_1[len_1]; 56 | int arr_2[len_2]; 57 | for(int j=0;j>arr_1[j]; 60 | } 61 | for(int j=0;j>arr_2[j]; 64 | } 65 | // 输入的数据已经是有序了,不需要再排序 66 | // sort(arr_1, arr_1+len_1); 67 | // sort(arr_2, arr_2+len_2); 68 | // 题目bug,不需要保留小数 69 | cout< 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | // leetcode 983 Minimum Cost For Tickets. 9 | // https://leetcode.com/problems/minimum-cost-for-tickets/ 10 | 11 | int func(int days[], int costs[], int len, int n_costs) 12 | { 13 | // dp[i]表示前i天旅行的费用 14 | int dp[366]; 15 | for(int i=0;i<366;i++) 16 | { 17 | dp[i] = INT_MAX; 18 | } 19 | // 前0天,没有旅行,没有费用 20 | dp[0] = 0; 21 | // 扫描days数组的下标 22 | int idx = 0; 23 | for(int i=1;i<366;i++) 24 | { 25 | // 第i天不旅行,防止idx下标出界 26 | // idx>=len必须放在前面,先进行判断,否则会造成缓冲区溢出 27 | if(days[idx] != i || idx>=len) 28 | { 29 | // 费用和之前保持不变 30 | dp[i] = dp[i-1]; 31 | } 32 | // 第i天旅行 33 | else 34 | { 35 | // 三种费用依次比较,注意防止i-1,i-7,i-30出了边界 36 | dp[i] = min(dp[i], ( i>=1 ? dp[i-1] : 0 ) + costs[0]); // 一天的费用 37 | dp[i] = min(dp[i], ( i>=7 ? dp[i-7] : 0) + costs[1]); // 七天的费用 38 | dp[i] = min(dp[i], ( i>=30 ? dp[i-30] : 0) + costs[2]); // 一个月的费用 39 | // 下一次旅行的日期 40 | idx++; 41 | } 42 | } 43 | return dp[365]; 44 | } 45 | 46 | int main() 47 | { 48 | const int n_costs = 3; 49 | int n_test; 50 | cin>>n_test; 51 | for(int i=0;i>len; 55 | int days[len]; 56 | int costs[n_costs]; 57 | for(int j=0;j>days[j]; 60 | } 61 | for(int j=0;j>costs[j]; 64 | } 65 | cout< 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int func(int n_egg, int n_floor) 8 | { 9 | vector> dp(n_floor+1, vector(n_egg+1, 0)); 10 | int m = 0; 11 | while (dp[m][n_egg] < n_floor) { 12 | m++; 13 | for (int k = 1; k <= n_egg; ++k) 14 | dp[m][k] = dp[m - 1][k - 1] + dp[m - 1][k] + 1; 15 | } 16 | return m; 17 | } 18 | 19 | int main() 20 | { 21 | int n_test; 22 | cin>>n_test; 23 | for(int i=0;i>n_egg; 28 | cin>>n_floor; 29 | cout<