牛客练习赛51 E 数列 (二分 + 贪心 + 思维)
大致题意
思路
关键在于贪心的证明比较有启发性。
官方题解:
链接:https://ac.nowcoder.com/discuss/248083?type=101
对于一个数列,如果其一个子数列a[i],a[i+1]…a[j-1],a[j]满足a[k]=a[k-1]+1(i+1<=k<=j),同时,也满足i-1<1或者a[i]!=a[i-1]+1,j+1>n或者a[j+1]!=a[j]+1,则我们称这样的子数列为一段。我们可以发现,假如数列中有sum个这样的段,则小乔对数列的喜爱度为n-sum。因为数列是可以自由填数的,所以对与每一段我们使得a[i]=1是最优的,a[i],a[i+1]…a[j-1],a[j]显然。于是对于每一段,如果这段的长度为s,按最优的方法填数,则这一段的总和为s*(s+1)/2。
于是问题转换为:
把数列n分成sum个段,要求最小化sum,并且所有段的总和<=m。
设这sum段中长度最小的段长度为mn,长度最大的段长度为mx,可以发现如果我们已知了sum,那么要使这sum段的总和最小,就要使得mn和mx尽可能的接近,因为如果mx-mn>=2,那么段mx的最后一个元素的值为mx,段mn最后一个元素的值为mn,那么我们使段mx的长度-1,mn的长度加1。那么总和的变化就是总和=总和-mx+mn+1。因为mx-mn>=2,所以mx>mn+1。
因此如果得知sum,最优的策略就是均分所有段的长度。
均分的方法就是,首先使每一段的长度为n/sum,剩余n%sum个匀速均分配到n%sum个段上去。
于是有n%sum个段的长度为n/sum+1,n-n%sum个段的长度为n/sum。
对于sum,我们二分答案,因为答案具有单调性,分段越多,可以使总和越小。
通过二分答案求出sum再构造数列即可。时间复杂度O(logn+n)
代码
#include<bits/stdc++.h> using namespace std; #define maxn 405 #define maxm 1000006 #define ll long long int #define INF 0x3f3f3f3f #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) #define mem(a) memset(a,0,sizeof(a)) #define sqr(x) (x*x) #define inf (ll)2e18+1 int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return f*x; } int n,m; bool pd(int x){ int len=n/x; int last=n%x; ll ss=1ll*len*(len+1)/2; ll ee=ss+len+1; return 1ll*(x-last)*ss+1ll*last*ee <= m; } int main() { n=read();m=read(); int l=1,r=n,ans=1; while(l<=r){ int mid=(l+r)>>1; if(pd(mid)){ ans=mid; r=mid-1; } else l=mid+1; } //printf("ans = %d\n",ans); int p=n%ans; int len=n/ans; inc(i,1,p)inc(j,1,len+1)printf("%d ",j); inc(i,1,ans-p)inc(j,1,len)printf("%d ",j); printf("\n"); return 0; }
- 牛客练习赛7 E 题 珂朵莉的数列 【树状数组 + 思维】
- 牛客练习赛13 A B C F【二分+思维】
- 牛客练习赛24-B-贪心
- 牛客练习赛6 D 世界上最可爱的珂朵莉 贪心
- 牛客练习赛13_C-幸运数字Ⅲ(思维)
- 牛客练习赛6 A 【二分】
- 牛客练习赛6 D 世界上最可爱的珂朵莉 贪心
- 牛客练习赛39——A.走方格(思维)
- 牛客练习赛6 D.世界上最可爱的珂朵莉 ( 贪心
- 牛客练习赛6 D 世界上最可爱的珂朵莉 贪心
- 牛客练习赛10 E 数列查找 [莫队+分块]
- 牛客练习赛6 D 世界上最可爱的珂朵莉 贪心
- 牛客练习赛6 D 世界上最可爱的珂朵莉 贪心
- 【牛客练习赛3-E.绝对半径2051】 二分+预处理
- 牛客练习赛6 D 世界上最可爱的珂朵莉 贪心
- 牛客练习赛13 D 题 幸运数字IV 【康拓逆展开 + 思维】
- 牛客练习赛7 E 珂朵莉的数列 (只有思路)
- HDU 4343 多查询求区间内的最大不相交区间个数-思维&贪心-卡时间&二分&剪枝
- 【牛客练习赛13】 A B C D【康拓展开】 E【DP or 记忆化搜索】 F 【思维】
- 牛客练习赛6 D 世界上最可爱的珂朵莉 贪心