算法设计与分析期中考试复习:代码和经典题目 分治二分动态规划(未完待续)
Posted karshey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法设计与分析期中考试复习:代码和经典题目 分治二分动态规划(未完待续)相关的知识,希望对你有一定的参考价值。
写在前面
自用的抱佛脚笔记。
代码可能跟书上不一样。
期中考试的范围:分治法和动态规划。
我的复习范围:
分治:快速排序,归并排序,二分查找,二分模板题(如派)。
动态规划:矩阵相乘,数塔,最长公共子序列,0-1背包。
快速排序
思想:
在数组a中找一个中枢元素x,用两个指针ij遍历数组:i从左往右,j从右往左;一开始i++,当出现a[i]>=x,i停止;j- -,当出现a[j]<=x时,j停止。
此时a[i]>=x,a[j]<=x,而我们需要的是x左边的数小于等于它,x右边的数大于等于它,因此swap(a[i],a[j]),继续执行i++,知道ij相遇。
排完一次之后x左边的数小于等于x,右边的数大于等于x;于是分别对x左边和右边进行快速排序。
#include<bits/stdc++.h>
using namespace std;
int n;
int a[200000+10];
void quick_sort(int l,int r)
{
if(l>=r) return;
int t=(l+r)/2;
int x=a[t];int i=l-1,j=r+1;
while(i<j)
{
do i++;while(a[i]<x);
do j--;while(a[j]>x);
if(i<j)swap(a[i],a[j]);//!!!一定要加if条件
}
quick_sort(l,j);
quick_sort(j+1,r);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
quick_sort(1,n);
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
return 0;
}
P1177 【模板】快速排序,可以在这里看看自己的快排模板写对没
归并排序
思想:
先一直分治,分到最小。然后开始排序。
取中点mid,由于前面的递归可知,mid左边和mid右边局部有序。
令i从l开始,j从mid+1开始,比较ij哪个小,小的放在新的数组里并指针往前移。
但凡有一个指针走完(i=mid或j=r),break;
则剩下的都是大的,直接接在新数组后。
然后新数组对旧数组赋值即可。
#include<bits/stdc++.h>
using namespace std;
int n;
int a[200000+10],b[200000+10];
void Merge_sort(int l,int r)
{
if(l>=r) return;
int mid=(l+r)/2;
Merge_sort(l,mid);
Merge_sort(mid+1,r);
int i=l,j=mid+1;
int k=0;
while(i<=mid&&j<=r)
{
if(a[i]<=a[j]) b[k++]=a[i++];
else b[k++]=a[j++];
}
while(i<=mid) b[k++]=a[i++];
while(j<=r) b[k++]=a[j++];
for(int ii=l,kk=0;ii<=r;ii++,kk++)
{
a[ii]=b[kk];
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
Merge_sort(1,n);
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
return 0;
}
依旧可以通过提交上面的模板题以判断自己写对没。
二分
一般l和r分为这两种(非浮点):
r=mid,l=mid+1;
l=mid,r=mid-1;//那么mid=(l+r+1),否则容易死循环
#include<iostream>
#include<math.h>
using namespace std;
const int N=1e4+10;
int n,f;
double a[N];
const double pi=acos(-1.0);
double sum=0;
double eps=1e-5;
int judge(double mid)
{
int flag=0;
for(int i=1;i<=n;i++)
{
if(a[i]>=mid)
{
flag+=a[i]/mid;
}
}
if(flag>=f) return 1;
else return 0;
}
int main()
{
int t;cin>>t;
while(t--)
{
cin>>n>>f;
f++;
sum=0;
for(int i=1;i<=n;i++)
{
int t;cin>>t;
a[i]=pi*t*t;
sum+=a[i];
}
double l=0,r=sum,mid;
while(r-l>eps)
{
mid=(l+r)/2;
if(judge(mid)) l=mid;
else r=mid;
}
cout.precision(3);
cout<<fixed<<mid<<endl;
}
}
矩阵相乘
困了,明天再说。
偷懒的函数
快排:sort()
二分查找:lower_bound(a,a+n,x),返回第一个大于等于x的地址,想知道位置就要减去a
以上是关于算法设计与分析期中考试复习:代码和经典题目 分治二分动态规划(未完待续)的主要内容,如果未能解决你的问题,请参考以下文章