CF888E Maximum Subsequence

CF888E Maximum Subsequence

有一种叫做折半搜索的好东西

我们把数列劈成两半,分别搜索,再合并

合并可以排序+二分或者排序+单调性

代码极短

#include<bits/stdc++.h>
using namespace std;
const int N=37;
const int M=5000005;
typedef long long ll;
int n;
ll m;
ll a[N];
int mi;
ll s1[M],s2[M];
int cnt1=0,cnt2=0;
ll ans=0;
ll llmax(ll x,ll y){
    return x>y?x:y;
}
inline void dfs(int x,ll val,int t,int o){
    if(x==t){
        if(o==1) s1[++cnt1]=val;
        else s2[++cnt2]=val;
        return;
    }
    dfs(x+1,val,t,o);
    dfs(x+1,(val+a[x+1])%m,t,o);
}
inline int serch(int x){
    int l=1,r=cnt2,ans=0;
    s2[0]=0;
    while(l<=r){
        int mid=(l+r)>>1;
        if(s2[mid]<x) ans=mid,l=mid+1;
        r=mid-1;
    }
    return s2[ans];
}
inline bool cmp(ll x,ll y){
    return x<y;
}
int main(){
    scanf("%d%d",&n,&m);
    mi=n/2;
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]),a[i]%=m;
    dfs(0,0,mi,1);
    dfs(mi,0,n,2);
    for(int i=1;i<=cnt1;i++) ans=llmax(ans,s1[i]);
    for(int i=1;i<=cnt2;i++) ans=llmax(ans,s2[i]);
    sort(s1+1,s1+cnt1+1,cmp);
    sort(s2+1,s2+cnt2+1,cmp);
    int j=cnt2;
    s2[0]=0;
    for(int i=1;i<=cnt1;i++){
        ans=llmax(ans,(s1[i]+s2[cnt2])%m);
        while(j>0&&s2[j]>=m-s1[i]) j--;
        ans=llmax(ans,(s1[i]+s2[j])%m);
    }
    printf("%lld\n",ans);
    return 0;
} 

原文地址:https://www.cnblogs.com/QYJ060604/p/11523275.html

时间: 2024-10-08 18:44:51

CF888E Maximum Subsequence的相关文章

CF888E Maximum Subsequence (折半枚举+ two-pointers)

题意 给定一个包含\(n\)个数的序列\(a\),在其中任选若干个数,使得他们的和对\(m\)取模后最大.(\(n\leq 35\)) 题解 显然,\(2^n\)的暴枚是不现实的...,于是我们想到了折半枚举,分成两部分暴枚,然后考虑合并,合并的时候用two-pointers思想扫一遍就行了. 其实这是一道折半枚举+Two-Pointers的很好的练手题 //最近CodeForces有点萎,可能会JudgementError,但已经评测过了,能AC,多交几次应该可以 #include <cstd

【CF888E】Maximum Subsequence 折半搜索

[CF888E]Maximum Subsequence 题意:给你一个序列{ai},让你从中选出一个子序列,使得序列和%m最大. n<=35,m<=10^9 题解:不小心瞟了一眼tag就一下子知道怎么做了,吓得我赶紧把tag屏蔽了. 我们将原序列拆成两半,每一部分都暴力搜索出所有的子序列之和,用set存起来.然后枚举前一半的所有子序列和,设其为x,则使得总和%m最大的右半部分子序列和一定是所有<m-x的数中最大的那个,在set里找一下前驱就行了. #include <cstdio&

Maximum Subsequence Sum - 最大子列和问题_C语言实现

第一次写这方面的blog.自己也是初次接触相关知识,写的有不妥的地方十分欢迎大家指正~ 这是浙大PAT上的一道算法题(据说是浙大04年研究生复试题),题目是这样的: Maximum Subsequence Sum Given a sequence of KK integers { N_1N?1??, N_2N?2??, ..., N_KN?K?? }. A continuous subsequence is defined to be { N_iN?i??, N_{i+1}N?i+1??, ..

PAT 1007——Maximum Subsequence Sum

Given a sequence of K integers { N1, N2, ..., NK }. A continuous subsequence is defined to be { Ni, Ni+1, ..., Nj } where 1 <= i <= j <= K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For examp

01-复杂度2. Maximum Subsequence Sum (25)

Given a sequence of K integers { N1, N2, ..., NK }. A continuous subsequence is defined to be { Ni, Ni+1, ..., Nj } where 1 <= i <= j <= K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For examp

数据结构练习 01-复杂度2. Maximum Subsequence Sum (25)

Given a sequence of K integers { N1, N2, ..., NK }. A continuous subsequence is defined to be { Ni, Ni+1, ..., Nj } where 1 <= i <= j <= K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For examp

Maximum Subsequence Sum(接上篇)

Given a sequence of K integers { N1, N2, ..., NK }. A continuous subsequence is defined to be { Ni, Ni+1, ..., Nj } where 1 <= i <= j <= K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For examp

1007. Maximum Subsequence Sum (25)

Given a sequence of K integers { N1, N2, ..., NK }. A continuous subsequence is defined to be { Ni, Ni+1, ..., Nj } where 1 <= i <= j <= K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For examp

Maximum Subsequence Sum 最大子序列和的进击之路

本文解决最大子序列和问题,有两个题目组成,第二个题目比第一个要求多一些(其实就是要求输出子序列首尾元素). 01-复杂度1 最大子列和问题   (20分) 给定KK个整数组成的序列{ N1??, N2??, ..., NK?? },"连续子列"被定义为{ N?i??, Ni+1 ..., Nj },其中 1≤i≤j≤K."最大子列和"则被定义为所有连续子列元素的和中最大者.例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4,