上升子序列(板子,二分优化)
int a[N];
int dp[N];
int main()
{
int len=0;
for(int i=1;i<=n;i++)
{
int l=0,r=len;
int mid=(l+r+1)>>1;
while(l<r)
{
if(dp[mid]<a[i])l=mid;
else r=mid-1;
}
len=max(len,r+1);
dp[r+1]=a[i];
}
cout<<len<<endl;
}
友好城市(贪心、动态规划)
有一条横贯东西的大河,河有笔直的南北两岸,岸上各有位置各不相同的N个城市。北岸的每个城市有且仅有一个友好城市在南岸,而且不同城市的友好城市不相同。每对友好城市都向政府申请在河上开辟一条直线航道连接两个城市,但是由于河上雾太大,政府决定避免任意两条航道交叉,以避免事故。编程帮助政府做出一些批准和拒绝申请的决定,使得在保证任意两条航道不相交的情况下,被批准的申请尽量多。
测试数据: 答案:4 7 22 4 2 6 10 3 15 12 9 8 17 17 4 2
将数据两两存入pair数组中进行保存,可以对数组的first进行从小到大排序,对数组的second序列求最大上升子序列,题目要求航道不应交叉,对于每个first,在排好序的情况下,若其second有了交叉,则必须有所取舍,从中选一,当选的是最长上升子序列,则一定可以选出最多的航道。
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
typedef pair<int,int>A;
const int N = 2e5+10;
const int M = 1e6+10;
A a[N];
int dp[M];
bool cmp(A e,A r)
{
return e.second<r.second;
}
int main()
{
int n;cin>>n;
for(int i=1;i<=n;i++)
{
int x,y;cin>>x>>y;dp[i]=1;
a[i].first=x;a[i].second=y;
}
sort(a+1,a+1+n,cmp);
int len=0;
for(int i=1;i<=n;i++)
{
int l=0,r=len;
while(l<r)
{
int mid=(l+r+1)>>1;
if(dp[mid]<a[i].first)l=mid;
else r=mid-1;
}
len=max(len,r+1);
dp[r+1]=a[i].first;
}
cout<<len;
}
拦截导弹(贪心,动态规划)
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度,计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
测试样例
389 207 155 300 299 170 158 65 答案:6 2 90 103 99 83 102 70 86 70 99 71 答案:5 3
计算最多能拦截多少导弹即是去求最长下降子序列的个数,拦截所有导弹最少要配置多少套即用贪心做法:
若所有序列结尾都小于当前导弹高度,即需要再配置一个设备。
若可以有序列结尾大于导弹高度,则找结尾最小的那个将导弹加入。
这里求最长下降子序列需要注意将数组反向。
#include<iostream>
#include<vector>
using namespace std;
const int N = 1e5+10;
int a[N];
int dp[N];
int g[N];
int main()
{
int n=1;
while(cin>>a[n])n++;
int maxa=0;
for(int i=n-1;i>=1;i--)
{
int l=0,r=maxa;
while(l<r)
{
int mid=(l+r+1)/2;
if(dp[mid]<=a[i])l=mid;//这里与模板不太一样,需要加一个等号,否则会出错。
else r=mid-1;
}
maxa=max(maxa,l+1);
dp[l+1]=a[i];
}
cout<<maxa<<endl;
int cnt=0;vector<int>v;
for(int i=1;i<=n-1;i++)
{
int j=0;
while(j<v.size()&&v[j]<a[i])j++;
if(j>=v.size())v.push_back(a[i]);
else v[j]=a[i];
}
cout<<v.size();
}