zoukankan      html  css  js  c++  java
  • BestCoder Round #89 02单调队列优化dp

    1、BestCoder Round #89  

    2、总结:4个题,只能做A、B,全都靠hack上分。。

    01  HDU 5944   水

    1、题意:一个字符串,求有多少组字符y,r,x的下标能组成等比数列。

    2、总结:有个坑,y,r,x顺序组公比q>1,也可反着来x,r,y顺序组。

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<cstdio>
    #include<map>
    #define F(i,a,b) for (int i=a;i<b;i++)
    #define FF(i,a,b) for (int i=a;i<=b;i++)
    #define mes(a,b) memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define LL long long
    using namespace std;
    const int N=10100,MAX=1000100;
    
    int main()
    {
        int t,a[N];
        char str[N];
        scanf("%d",&t);
        while(t--){
            scanf("%s",str+1);      //才知道可以这样输
            int len=strlen(str+1),sum=0;       //str+1
            for(int i=1;i<=len;i++) {
                if(str[i]=='y') {
                    for(int j=2;i*j*j<=len;j++) {
                        if(str[i*j]=='r'&&str[i*j*j]=='x') {
                            sum++;
                        }
                    }
                }
            }
            for(int i=1;i<=len;i++) {   
                if(str[i]=='x') {       //x,r,y反顺序扫一遍
                    for(int j=2;i*j*j<=len;j++) {
                        if(str[i*j]=='r'&&str[i*j*j]=='y') {
                            sum++;
                        }
                    }
                }
            }
            cout<<sum<<endl;
        }
    
        return 0;
    }
    View Code

    02  HDU 5945   好题,单调队列优化的dp

    1、题意:给出x,k,t三个数,目的是将x变到1。有两种操作,1.X=X−i(0<=i<=t).  2.if k|X,X=X/k.

    2、总结:还不太懂单调队列,看了一个黄名爷的代码。只是这题本来也好坑,hack之后就没几个过了的。

    3、思路:设f[i]表示将i变到1所需的最小步骤。如果k|i , f[i]=min( f[j] , f[i/k] ); 否则f[i]=min( f[j] ),其中i-t<=j<=i-1。这里要快速求出min( f[j] ),用单调队列维护一下即可,时间复杂度为O(n)。

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<cstdio>
    #define F(i,a,b) for (int i=a;i<b;i++)
    #define FF(i,a,b) for (int i=a;i<=b;i++)
    #define mes(a,b) memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define LL long long
    using namespace std;
    const int N=1000100;
    
    //一开始把这两个数组放main()里面直接就溢出了
    int f[N],q[N];  //f[i]表示将i变到1的操作次数q[i],q[N]存储i-t<=j<=i-1范围的位置,并且单调递增
    int main()
    {
        int T,x,k,t;
        scanf("%d",&T);
        while(T--) {
            scanf("%d%d%d",&x,&k,&t);
            int head=1,tail=0;
            q[++tail]=1;
            mes(f,INF); f[1]=0;
            for(int i=2;i<=x;i++) {
                if(i%k==0) f[i]=f[i/k]+1;
                while(i-t>q[head]&&head<=tail)  head++;     //不符合的弹出
                if(head<=tail) f[i]=min(f[i],f[q[head]]+1); //f[i]=min( f[j] )
                q[++tail]=i;        //位置压入队列
                while(head<tail&&f[q[tail]]<f[q[tail-1]]) q[tail-1]=q[tail],tail--; //要使f[q[head]]=min( f[j] ),所以q中不符合单调递增的就去掉; 注意head<tail,如果==就说明q中只存了一个位置,也就没必要进行这一步
            }
            printf("%d
    ",f[x]);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    JVM之内存区域
    记录Spring Boot小项目的一些坑
    JVM之编译OpenJDK
    Java容器之HashMap源码分析1
    IO流(1)--文件流及其原理
    IO流(0)
    Java中的字节和字符
    整理全网优秀的API接口设计及相关优秀的接口管理、在线文档生成工具
    关于智慧城市的建设方案和资料,相关内容大多来源于互联网,收集整理方便项目经理、产品经理、相关交通领域公司的使用
    整理可视化大屏设计教程与相关资源,大屏设计,可视化
  • 原文地址:https://www.cnblogs.com/sbfhy/p/6012350.html
Copyright © 2011-2022 走看看