HDU 3474 单调队列

点击打开链接

题意:给个成环的字符串,现在要从一个地方断开这个环,然后可以向左或向右走,在走的过程中C的数量要始终保持大于J的数量,问共有多少个这样的端点

思路:没有思路,参考了大神的思路,大神说这是水题,弱哭~~~~,这里解释一下L和R数组的含义应该就可以自己把代码敲出来了,貌似单调队列考的就是这个呢,L数组保存的是从0到i的最小num值,num为前缀和,这里设C为1,J为-1然后求前缀和,R数组是从最后以为到i的最小num值,然后对于判断的条件,这道题写两遍就行了,一次是全都向左走,另一次是全都向右走,写了一个第二个基本完全一样,说一下判断条件,对于当前节点i,它可以的情况是它到右侧的最小值要>=0,即R[i+1]-num[i]>=0,num[i]及它前面的C和J全部去掉了,然后R[i+1]减去它就是后面最小的情况,只有大于等于0才可以继续,然后是后边的那部分加上前边的部分,即num[len]-num[i]+L[i]>=0,后面剩下的和与前边最小的相加,若小于0则说明不可以,反之你懂得,然后另一个方向处理的相同

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=1000010;
char str[maxn];
int L[maxn],R[maxn],num[maxn],vis[maxn];
void init(int len){
    L[1]=num[1];
    for(int i=2;i<=len;i++) L[i]=min(L[i-1],num[i]);
    R[len]=num[len];
    for(int i=len-1;i>=1;i--) R[i]=min(R[i+1],num[i]);
}
int main(){
    int T,cas=1;
    scanf("%d",&T);
    while(T--){
        scanf("%s",str);
        int len=strlen(str);
        memset(vis,0,sizeof(vis));
        num[0]=0;
        for(int i=0;i<len;i++){
            if(str[i]=='C') num[i+1]=num[i]+1;
            else num[i+1]=num[i]-1;
        }
        init(len);
        if(L[len]>=0) vis[0]=1;
        for(int i=1;i<len;i++){
            if(R[i+1]-num[i]>=0&&num[len]-num[i]+L[i]>=0) vis[i]=1;
        }
        num[0]=0;
        int t=0;
        for(int i=len-1;i>=0;i--){
            if(str[i]=='C') num[t+1]=num[t++]+1;
            else num[t+1]=num[t++]-1;
        }
        init(len);
        if(L[len]>=0) vis[0]=1;
        for(int i=1;i<len;i++){
            if(R[i+1]-num[i]>=0&&num[len]-num[i]+L[i]>=0) vis[len-i]=1;
        }
        int ans=0;
        for(int i=0;i<len;i++) if(vis[i]) ans++;
        printf("Case %d: %d\n",cas++,ans);
    }
    return 0;
}
时间: 2024-11-01 20:56:02

HDU 3474 单调队列的相关文章

HDU 3507 单调队列 斜率优化

斜率优化的模板题 给出n个数以及M,你可以将这些数划分成几个区间,每个区间的值是里面数的和的平方+M,问所有区间值总和最小是多少. 如果不考虑平方,那么我们显然可以使用队列维护单调性,优化DP的线性方法来做,但是该题要求的是区间和的平方,于是要转换单调的计算方法为斜率,也就是凸线. 其他就是最基本的单调DP /** @Date : 2017-09-04 15:39:05 * @FileName: HDU 3507 单调队列 斜率优化 DP.cpp * @Platform: Windows * @

HDU 3530 单调队列

Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3995    Accepted Submission(s): 1308 Problem Description There is a sequence of integers. Your task is to find the longest subsequenc

hdu 3415 单调队列

Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5690    Accepted Submission(s): 2059 Problem Description Given a circle sequence A[1],A[2],A[3]......A[n]. Circle s

hdu 3401 单调队列优化+dp

http://acm.hdu.edu.cn/showproblem.php?pid=3401 Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5188    Accepted Submission(s): 1776 Problem Description Recently, lxhgww is addicted to stoc

hdu 3401(单调队列优化dp)

注意:这题题意是有操作的天数相隔要大于w 然后列出状态转移方程就可以发现,可以用优点队列优化啦. 构造状态dp[i][j]表示第i 天拥有 j只股票的时候,赚了多少钱 状态转移有: 1.从前一天不买不卖: dp[i][j]=max(dp[i-1][j],dp[i][j]) 2.从前i-W-1天买进一些股: dp[i][j]=max(dp[i-W-1][k]-(j-k)*AP[i],dp[i][j]) 3.从i-W-1天卖掉一些股: dp[i][j]=max(dp[i-W-1][k]+(k-j)*

hdu 4193 单调队列

题意是给你n个数   组成的环   求以一个数开头 的数列所有前缀都为非负数的数列的个数: 思路:  先扩展成2*n的数列 然后求出sum[i]表示前i项的和     对每个i>.=n结尾的数列  只要单调队列里的最小值大于等于sum[i-n]就满足情况(想想为什么)   对于单调队列  只要维护长度大于等于n   递增的就行: #include<stdio.h> #include<string.h> #include<iostream> using namesp

hdu 4374 单调队列

求最大不超过k的连续子序列的和   单调队列 #include<stdio.h> #include<string.h> #include<iostream> using namespace std; int num[201000],id[201000],sum[201000]; int main() { int n,m,i,j,T; scanf("%d",&T); while(T--) { scanf("%d%d",&am

hdu 3530 单调队列水题

给你一个数列找到最长的子序列   中的最大值减最小值值m   k之间 建立两个单调队列   一个递增    一个递减    当两个队首满足情况是就进行比较 找到最大值 当不满足是旧的移动队首      怎样移??? 移动队首id较小的一个 #include<stdio.h> #include<string.h> #include<iostream> using namespace std; int max(int a,int b) { return a>b?a:b

HDU 4122 单调队列

转载自:http://blog.csdn.net/lvshubao1314/article/details/46910271 DES :给出n个订单和m是商店的开放时间.然后n行给出n个订单的信息.然后给出t和s.表示一个月饼的保质期和保存一天的成本.最后m行,给出每个时刻做月饼的成本.问.完成订单的最少的成本是多少. 思路就是用单调队列保存每个点之前的可以为这个点做月饼的点.刚学了单调队列.在保存下标然后找到值哪里还是有一些混乱. 第一次错了.闰年是366天.搞混了.T_T.不过时间方面的计算