算法考试专项复习笔记2(贪心和递归)

贪心算法

活动安排问题

设有n个活动的集合E={1,2,3,…,n},所有的活动要求使用同一资源,而在同一时间内只有一个活动能使用这一资源,每个活动都有使用这一资源的开始时间si和结束时间fi,且si 贪心策略:先按右端点从小到大排序,再按左端点从小到大。

#include
#include
using namespace std;
const int N = 1e5 + 10;
typedef struct Node{
	int begin, end;
}Node;
Node a[N];
//比较,按照结束时间从小到大排序
int cmp(Node a, Node b){
	return a.end < b.end;
}
int main()
{
	int n;
	scanf_s("%d", &n);
	for (int i = 0; i < n; i++)
		scanf_s("%d%d", &a[i].begin, &a[i].end);
	//函数
	sort(a, a + n, cmp);
	int ans = 1;
	int end = a[0].end;
	for (int i = 1; i < n; i++){
		if (end < a[i].begin){
			end = a[i].end;
			ans++;
		}
	}
	printf("%d", ans);
	return 0;
}

加油的问题

John 准备驾车从 S 地驶往 T 地,油箱加满时可行驶 k 公里。两地之间有 n 个加油 站,加油站之间的距离 John 已经知道。John 希望在沿途尽可能少的停留加油。设计算法, 确定应在哪些加油站加油,以满足 John 的愿望。

#include 
int main()
{
	int n,k,i;
	int *distance;
	int count=1;
	int rest;
	scanf("%d%d",&n,&k);
	distance=new int[k+1];
	printf("input the distance:");
	for(i=0;i<k+1;i++)
		scanf("%d",&distance[i]);		
	rest=n;
	for(i=0;i<k+1;i++){
		if(rest>=distance[i])
			rest-=distance[i];
		else{
			count++;
			rest=n;
		}
	}
	printf("count=%d\n",count);
	return 0;
}

递归算法

棋盘覆盖问题

算法考试专项复习笔记2(贪心和递归)_第1张图片

//棋盘覆盖
#include
const int N = 8 ;
//t(x,y) -> top-left :左上角的坐标
//s(x,y) -> special  :特殊标识的坐标
//L     :   讨论当前方格的边长
//tag   :   时间戳
int chessboard[N][N] ;
int tag = 1 ;
void f( int tx , int ty , int sx , int sy , int L ){if( L == 1 ){
        return ;
    }
    int t = tag ++ ;
    int len = L / 2 ;//判断特殊点是否在左上部分?
    if( sx < tx + len && sy < ty + len ){
        //继续分治
        f( tx , ty , sx , sy , len );
    }
    else{
        //填上序号,并继续分治
        chessboard[tx+len-1][ty+len-1] = t ;
        f( tx , ty , tx+len-1 , ty+len-1 , len );
    }//判断特殊点是否在右上部分?
    if( sx < tx + len &&  ty + len <= sy ){
        //继续分治
        f( tx , ty + len , sx , sy , len );
    }
    else{
        //填上序号,并继续分治
        chessboard[tx+len-1][ty+len] = t ;
        f( tx , ty + len , tx+len-1, ty+len , len );
    }//判断特殊点是否在左下部分?
    if( tx + len <= sx && sy < ty + len ){
        //继续分治
        f( tx + len , ty , sx , sy , len );
    }
    else{
        //填上序号,并继续分治
        chessboard[tx+len][ty+len-1] = t ;
        f( tx + len , ty , tx+len , ty+len-1 , len );
    }//判断特殊点是否在右下部分?
    if( tx + len <= sx && ty + len <= sy ){
        //继续分治
        f( tx + len , ty + len , sx , sy , len );
    }
    else{
        //填上序号,并继续分治
        chessboard[tx+len][ty+len] = t ;
        f( tx + len , ty + len , tx+len , ty+len , len );
    }
​
​
}
int main()
{
    //棋盘初始左上角,初始特殊点,边长为8
    f( 0 , 0 , 0 , 1 , 8 );
    for( int i = 0 ; i < 8 ; i++ ){
        for( int j = 0 ; j < 8 ; j++ ){
            printf("%4d",chessboard[i][j]);
        }
        putchar('\n');
    }
    return 0 ;
}

二分搜索

int binarySearch(int a[],int l,int r,int x){
	if(r<l)
		return -1;
	mid=(l+r)/2;
	if(a[mid]==x)
		return mid;
	if(x>a[mid])
		return binarySearch(a,mid+1,r,x);
	else
	    return binarySearch(a,l,mid-1,x);
}

你可能感兴趣的:(一些需要记录的东西)