二分二题-P1678,P3902【二分,LIS】
生活随笔
收集整理的這篇文章主要介紹了
二分二题-P1678,P3902【二分,LIS】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
T1:P1678 煩惱的高考志愿
評測記錄:https://www.luogu.org/record/show?rid=9644174
大意
有m個分數線,有n個估分,給每個估分找一個最接近的分數線,輸出每個估分和它最接近的分數線的差之和。
解題思路
我們先將分數排序
我們可以找到一個估分的分數線前驅,那么這個的后一個就是這個估分的分數線后繼,那么我們將估分和這兩個的差取最小值就是最接近的分數線。然后第一個和最后一個特殊處理一下就好了。
code
#include<cstdio> #include<algorithm> using namespace std; int n,m,a[100001],f,l,r,mid,ans; int finds(int x)//查找前驅 {int l=1,r=n,mid;while (l<r){mid=(l+r+1)/2;if (a[mid]<=f) l=mid;else r=mid-1;}return l; } int main() {scanf("%d%d",&n,&m);for (int i=1;i<=n;i++)scanf("%d",&a[i]);sort(a+1,a+1+n);for (int i=1;i<=m;i++){scanf("%d",&f);int fd=finds(f);if (fd==1&&f<a[fd]||fd==n) ans+=abs(f-a[fd]);//特判else ans+=min(f-a[fd],a[fd+1]-f);//取最小}printf("%d",ans); }T2:P3902 遞增
評測記錄:https://www.luogu.org/recordnew/lists?uid=52918&pid=P3902
大意
一個長度為nn的序列aa,求至少修改多少個數可以使這個序列變成最長上升子序列。
解題思路
我們可以先求出這個序列的最長上升子序列,然后修改不在這個序列內的數就好了,那么答案就是n?LISnumn?LISnum
code
#include<cstdio> using namespace std; int n,a[100001],tail,h[100001]; int finds(int x)//查找前驅 {int l=1,r=tail,mid;while (l<r){mid=(l+r)/2;if (h[mid]<x) l=mid+1;else r=mid;}return l; } int main() {scanf("%d",&n);for (int i=1;i<=n;i++)scanf("%d",&a[i]);tail=0;for (int i=1;i<=n;i++){if (a[i]>h[tail]) h[++tail]=a[i];//加入序列else h[finds(a[i])]=a[i];//修改序列}printf("%d",n-tail);//輸出答案 }總結
以上是生活随笔為你收集整理的二分二题-P1678,P3902【二分,LIS】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 甩锅局什么意思 甩锅局的含义
- 下一篇: 二分答案二题-P1182数列分段II,P