位子

排序初步

久未见 提交于 2020-01-19 12:04:08
简单排序 如果有N个元素需要排序,那么首先从N个元素中找到最小的那个(称为第0 小的)放在第0个位子上(和原来的第0个位子上的元素交换位置),然后再从剩 下的N-1个元素中找到最小的放在第1个位子上,然后再从剩下的N-2个元素 中找到最小的放在第2个位子上……直到所有的元素都就位。 总共执行了1,2,3,4,5。。。。n次即s(s-1)/2,量级是s2 #include <iostream> #include <cstdio> using namespace std; void SelectSort(int a[],int size){ for(int i=0;i<size;i++){//每次循环后将第i小的元素放好 int tmpMin=i;//用来记录从第i个到第size-1个元素中,最小的那个元素的下标 for(int j=i+1;j<size;j++){ if(a[j]<a[tmpMin])tmpMin=j; } //下面将第i小的元素放在第i个位子上,并将原来占着第i个位子的元素挪到后面 int tmp=a[i]; a[i]=a[tmpMin]; a[tmpMin]=tmp; } //输出 for(int i=0;i<size;i++){ cout <<a[i]<<" "; } } int main(){ int a[5]={85,34,23,29,100};

CodeForces - 834D(线段树优化dp)

匿名 (未验证) 提交于 2019-12-03 00:32:02
给你长度为N的一个序列,让你将其分成连续的k段,每段的价值为其中数字种类的个数,求最大价值总和。 首先能想到n^2复杂度的dp 设定dp[i][j]表示到位子i,分成j段的最大价值总和。 dp[i][j] =max( d p[i][j] , dp[k][j-1] +val(k+1,i) );k为这个数上一次出现的位置 可以用线段树加速转移。 考虑val(k+1,j). 我们遍历到第j个位子的时候,我们显然树上第k个位子表示的是 dp[k][j-1] + val(k+1,i) ,那么考虑第i个数,它会对区间 (pre[a[i]] ,i-1)区间内的树上的位子有所影响。 那么我们遍历到第i个位子的时候,将树上区间(pre[a[i]],i)的值都+1。 这里pre[a[i]]表示的是a[i]这个数上一次出现的位子。 #include<bits/stdc++.h> using namespace std; const int maxn = 35555; int a[maxn<<2],n,k; int delt[maxn<<2],pre[maxn],pos[maxn]; int dp[maxn][52]; void pushup(int rt) { a[rt]=max(a[rt*2],a[rt*2+1]); } void pushdown(int rt) { delt[rt<<1]+

插入排序算法的思想

匿名 (未验证) 提交于 2019-12-02 23:59:01
原始数组:a=[8,6,2,3,7,9,1]; 要求升序。 step1:因为8是第一个,所以8固定不动,让6和8比,因为6小于8,所以,6和8交换位子,数组变为6,8,2,3,7,9,1。这1轮比较完毕。 step2:将2与它的前一个,也就是8比,因为2小于8,所以2和8交换位子,数组变为6,2,8,3,7,9,1。 再将2与6比,比完之后2与6交换位子,数组变为2,6,8,3,7,9,1。这一轮比较完毕。 step3:将3与8比,所以3与8交换位子,数组变为2,6,3,8,7,9,1。 将3与6比,所以3和6交换位子,得到2,3,6,8,7,9,1。 将3与2比,因为3不比2小,所以位子不变,跳出循环,跳出这一轮比较。 step4:以此类推…… 代码为 1 for ( int i = 1 ; i < n ; i ++) { //外层循环 ,整个过程其实就是在为a[i]寻找合适的插入位子 2 for ( int j = i , j > 0 ; j --) { //内层循环,因为是倒回去比较,所以是减减 3 if ( a [ i ]< a [ j ]) 4 swap ( a [ i ], a [ j ]); //swap函数的作用就是交换位子 5 else break 6 } 7 } 如果想把代码的行数写少点,可以把上述代码修改一下, 1 for ( int i = 1 ; i <