• 【BJOI2019】奥术神杖


    题面

    https://www.luogu.org/problem/P5319

    追不到北京的小姐姐,只能写北京的省选了。。。。

    题解

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cmath>
    #include<vector>
    #define N 2000
    #define M 2000
    #define eps 1e-7
    #define INF 1000000007.0
    #define ri register int
    using namespace std;
    
    struct node{
      int pre,trans;
    } g[N][M];
    
    char s[N];
    char t[N];
    int n,m;
    
    struct AC{
      int nex[N],ch[N][10];
      int cnt[N];
      double v[N],nv[N];
      double f[N][M];
      vector<int> son[N];
      int tot;
      void insert(double x) {
        int now=0;
        for (ri i=1,l=strlen(s+1);i<=l;i++) {
          int c=s[i]-'0';
          if (!ch[now][c]) ch[now][c]=++tot;
          now=ch[now][c];
        }
        cnt[now]++;
        v[now]=x;
      }
      void getfail() {
        queue<int> q;
        for (ri i=0;i<=9;i++) if (ch[0][i]) q.push(ch[0][i]);
        while (!q.empty()) {
          int x=q.front(); q.pop();
          for (ri i=0;i<=9;i++) {
            int y=ch[x][i];
            if (!y) ch[x][i]=ch[nex[x]][i]; else nex[y]=ch[nex[x]][i],q.push(y);
          }
        }
      }
      void dfs(int x){
        nv[x]+=nv[nex[x]];
        for (ri i=0;i<son[x].size();i++) {
          dfs(son[x][i]);
        }
      }
      void init() {
        for (ri i=1;i<=tot;i++) son[nex[i]].push_back(i);
      }
      bool check(double mid) {
        double dv=log(mid)/log(1.0001);
        for (ri i=0;i<=tot;i++) nv[i]=v[i]-dv*cnt[i];
        dfs(0);
        for (ri i=0;i<=n;i++)
          for (ri j=0;j<=tot;j++) f[i][j]=-INF;
        f[0][0]=0;
        for (ri i=0;i<=n-1;i++) if (t[i+1]=='.') {
          for (ri j=0;j<=tot;j++) 
            for (ri c=0;c<=9;c++) if (f[i][j]+nv[ch[j][c]]>f[i+1][ch[j][c]]) {
              g[i+1][ch[j][c]]=(node){j,c};
              f[i+1][ch[j][c]]=f[i][j]+nv[ch[j][c]];
            }
        }
        else {
          for (ri j=0;j<=tot;j++) 
            for (ri c=t[i+1]-'0';c<=t[i+1]-'0';c++) if (f[i][j]+nv[ch[j][c]]>f[i+1][ch[j][c]]) {
              g[i+1][ch[j][c]]=(node){j,c};
              f[i+1][ch[j][c]]=f[i][j]+nv[ch[j][c]];
            }
        }
        for (ri i=0;i<=tot;i++) if (f[n][i]>0) return 1;
        return 0;
      }
      void print() {
        int p=0;
        for (ri i=0;i<=tot;i++) if (f[n][i]>f[n][p]) p=i;
        int ss[N];
        for (ri i=n;i>=1;i--) {
          ss[i]=g[i][p].trans;
          p=g[i][p].pre;
        }
        for (ri i=1;i<=n;i++) cout<<ss[i];
      }
    } trie;
    
    int main(){
      scanf("%d %d",&n,&m);
      scanf("%s",t+1);
      double x;
      for(ri i=1;i<=m;i++) {
        scanf("%s %lf",s+1,&x);
        trie.insert(log(x)/log(1.0001));
      }
      trie.getfail();
      trie.init();
      double lb=1.0,rb=1e9;
      for (ri i=1;i<=45;i++) {
        double mid=(lb+rb)/2.0;
        if (trie.check(mid)) lb=mid; else rb=mid;
      }
      //cout<<lb<<endl;
      trie.print();
      return 0;
    }
  • 相关阅读:
    MySQl查询语句大全
    并发编程三
    并发编程二
    并发编程
    网络编程
    面向对象高级进阶
    python中的面向对象和面向过程
    为什么还需要学习TypeScript
    Chrome 神器,神奇的技巧
    vue-property-decorator知识梳理
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11279451.html
Copyright © 2020-2023  润新知