zoukankan      html  css  js  c++  java
  • [luogu_U15116]珈百璃堕落的开始

    https://www.zybuluo.com/ysner/note/1239458

    题面

    给定(n)个二元组((x,y)),问有多少种方案,使得选出其中几个后,(sum x=sum y)

    • (nmleq5*10^7,mleq10^6)

    解析

    在打比赛时又被傻逼DP切了
    考虑到我们关注的是(x-y),我们可以维护一维状态(x-y)以代替(x,y)两维状态。
    于是设(f[i][j])表示在第(1-i)个数中,(x-y=j)的方案数。
    (x-y)可以为负,记得开大空间。
    转移显然。

    但有几个要注意的地方。
    如果暴力枚举(j),复杂度可以达到(O(10^6n)),数据没有保证(n)这样能过。
    注意到(10^6)中有很多转移是从不合法状态转移到不合法状态。
    既然开始状态为(f[0][10^6])(防止状态出现负数),范围很小。我们可以维护一下当前被转移到了的区间范围,这样能大大降低时间复杂度。

    还有,(dp)值的边界条件要求必须能把未转移到的状态和转移到的状态区分开来
    所以初始所有(dp)值要设为(-inf)(dp[0][10^6])除外。

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #define re register
    #define il inline
    #define ll long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int N=2e6+100,M=1e6;
    int n,m,s[N],c[N],len,dp[2][N];
    char a[N];
    il ll gi()
    {
       re ll x=0,t=1;
       re char ch=getchar();
       while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
       if(ch=='-') t=-1,ch=getchar();
       while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
       return x*t;
    }
    int main()
    {
      n=gi();
      fp(i,1,n)
        {
          scanf("%s",a+1);len=strlen(a+1);
          fp(j,1,len) if(a[j]=='s') s[i]++;else if(a[j]=='c') c[i]++;
        }
      re int now=1,nxt=0,lasx=M,lasm=M,mn=M,mx=M;
      memset(dp,-63,sizeof(dp));dp[1][M]=0;
      fp(i,1,n)
      {
        swap(now,nxt);
        fp(j,lasm,lasx)
        {
          dp[now][j+s[i]-c[i]]=max(dp[now][j+s[i]-c[i]],dp[nxt][j]+s[i]);
          dp[now][j]=max(dp[now][j],dp[nxt][j]);
          dp[nxt][j]=0;
          mx=max(mx,j+s[i]-c[i]),mn=min(mn,j+s[i]-c[i]);
        }
        lasx=mx;lasm=mn;
      }
      printf("%d
    ",dp[now][M]);
      return 0;
    }
    
  • 相关阅读:
    swift 自学小计
    修改非空表字段类型Oracle
    DBNull.value
    修改SqlServer字段长度
    未在本地计算机上注册“Microsoft.Ace.OleDB.12.0”
    引用dll文件要复制到本地
    oracle与SqlServer连接串服务器地址
    生成几乎永不重复的串
    安装SqlServer2008后vs中dev控件消失
    Ios项目添加Pods
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9427219.html
Copyright © 2011-2022 走看看