[CF 137E] 求最长的连续和>=0 的序列

这篇博客介绍了如何利用栈解决寻找数组中最长连续子序列,使得子序列的和大于等于0的问题。通过降序排列前缀和,然后遍历数组,将符合条件的下标存入栈中,并在栈中进行二分查找,更新最优解,从而找到最长子序列的长度。
部署运行你感兴趣的模型镜像

因为和 = pre[i] - pre[j] .,将前缀和降序放到一个数组里面,然后二分

跟妹子的QQ,说了方法:

KissBuaa.Ds(AC) 21:22:00 

方法是这样—— 

KissBuaa.Ds(AC) 21:22:03 

搞一个栈 

KissBuaa.Ds(AC) 21:22:10 

依次从1~n 

KissBuaa.Ds(AC) 21:22:12 

遍历 

KissBuaa.Ds(AC) 21:22:26 

如果dp[i] >=0 那么局部最优长度就是i 

KissBuaa.Ds(AC) 21:22:38 

如果dp[i] < dp[stack最上面的元素】 

KissBuaa.Ds(AC) 21:22:49 

那么把i加到stack里面 

KissBuaa.Ds(AC) 21:23:11 

也就是stack记录的是下标,然后是递减的 

KissBuaa.Ds(AC) 21:23:14 

这个很好想。。。 

KissBuaa.Ds(AC) 21:23:21 

你每次到一个地方,不久要dp[i] - dp[j]么 

KissBuaa.Ds(AC) 21:23:25 

让dp[j] 递减 

KissBuaa.Ds(AC) 21:23:29 

那么-dp[j] 递增 

KissBuaa.Ds(AC) 21:23:31 

于是 

KissBuaa.Ds(AC) 21:23:37 

在i = 1 ~ n 的时候 

KissBuaa.Ds(AC) 21:23:47 

每次如果 dp[i] < dp[stack最上面的元素] 

KissBuaa.Ds(AC) 21:23:52 

那么i加到stack里面 

KissBuaa.Ds(AC) 21:24:02 

然后在stack里面二分,找到—— 

KissBuaa.Ds(AC) 21:24:17 

“最靠前的,并且dp[i] - dp[stack[ans]]>=0” 

KissBuaa.Ds(AC) 21:24:25 

那么当前最优解就是 i - stack[ans] 

KissBuaa.Ds(AC) 21:24:37 

也就是从stack[ans]+1 ------- i 这一段长度 

KissBuaa.Ds(AC) 21:24:40 

然后遍历一遍 

KissBuaa.Ds(AC) 21:24:46 

就能求出最长的长度是多少了 

KissBuaa.Ds(AC) 21:24:54 

知道这个了,那么数一数就行了。。。 


头文件就不附送了,反正给了老婆一份。。。好好用啊!

string str;
const int N = 400000;
int dp[N],n , st[N] , top;
bool check(char c){
    return c == 'a' || c == 'A' || c == 'i' || c == 'I' || c == 'e' || c == 'E' || c == 'o' || c == 'O' || c == 'u' || c == 'U';
}
void solve(){
    dp[0] = 0;
    n = str.length();
    for (int i = 1 ; i <= n ; ++ i){
        if (check(str[i-1])) dp[i] = dp[i-1] - 1;
        else dp[i] = dp[i-1] + 2;
    }
    int ans = 0 ;
    top = 0;
    //cout << st[0] << endl;
    for (int i = 1 ; i <= n ; ++i){
        if (top == 0 || dp[i] < dp[ st[top-1] ])
            st[top ++ ] = i;
        if (dp[i] >= 0){
            ans = max(ans , i);
            continue;
        }
        int low = 0 , high = top - 1 , mid , ret = i;
        do{
            mid = (low + high) >> 1;
            if (dp[i] - dp[ st[mid] ] >= 0){
                ret = min(ret , st[mid]);
                high = mid - 1;
            }
            else{
                low = mid + 1;
            }
        }while (low <= high);
        //cout << dp[i] << " " << ret << endl;
        ans = max(ans , i - ret);
    }
    int cnt = 0;
    for (int i = 1 ; i + ans - 1 <= n; ++i)
        if (dp[i + ans - 1] - dp[i - 1] >=0) ++cnt;
    if (ans == 0) printf("No solution\n");
    else{
        printf("%d ",ans);
        printf("%d\n",cnt);
    }
}
int main(){
    while (cin >> str) solve();
}


您可能感兴趣的与本文相关的镜像

PyTorch 2.6

PyTorch 2.6

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值