• Ring HDU


    题意:

    就是现在给出m个串,每个串都有一个权值,现在你要找到一个长度不超过n的字符串,

    其中之前的m个串每出现一次就算一次那个字符串的权值,

    求能找到的最大权值的字符串,如果存在多个解,输出最短的字典序最小的串。

    当最大全权值为0时输出空串。

    输入最多100个子串,权值为不超过100的正整数。

    每个子串长度至少为1,不超过10, n <= 50

    如果不考虑方案输出,这题就变得相当简单了。

    dp【i】【j】表示走到长度为 i 的时候 ,到AC自动机 j 这个节点所获得的最大权值和。

    我一开始的做法是在dp的过程中获得那个最优方案。

    最后死活过不去,就换了一种超级暴力的写法。

    将所有情况保存下来,去一个个找字典序最小的方案。

      1 #include <set>
      2 #include <map>
      3 #include <stack>
      4 #include <queue>
      5 #include <cmath>
      6 #include <cstdio>
      7 #include <string>
      8 #include <vector>
      9 #include <time.h>
     10 #include <cstring>
     11 #include <iostream>
     12 #include <algorithm>
     13 
     14 #define  pi acos(-1.0)
     15 #define  eps 1e-9
     16 #define  fi first
     17 #define  se second
     18 #define  rtl   rt<<1
     19 #define  rtr   rt<<1|1
     20 #define  bug               printf("******
    ")
     21 #define  mem(a, b)         memset(a,b,sizeof(a))
     22 #define  name2str(x)       #x
     23 #define  fuck(x)           cout<<#x" = "<<x<<endl
     24 #define  sf(n)             scanf("%d", &n)
     25 #define  sff(a, b)         scanf("%d %d", &a, &b)
     26 #define  sfff(a, b, c)     scanf("%d %d %d", &a, &b, &c)
     27 #define  sffff(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
     28 #define  pf                printf
     29 #define  FIN               freopen("../date.txt","r",stdin)
     30 #define  gcd(a, b)         __gcd(a,b)
     31 #define  lowbit(x)         x&-x
     32 #define  IO                iOS::sync_with_stdio(false)
     33 
     34 
     35 using namespace std;
     36 typedef long long LL;
     37 typedef unsigned long long ULL;
     38 const int maxn = 1e6 + 7;
     39 const int maxm = 8e6 + 10;
     40 const int INF = 0x3f3f3f3f;
     41 const int mod = 20090717;
     42 
     43 
     44 char str[105][12];
     45 int n, m, cost[105];
     46 
     47 
     48 struct Aho_Corasick {
     49     int next[1010][26], fail[1010], End[1010];
     50     int root, cnt;
     51 
     52     int newnode() {
     53         for (int i = 0; i < 26; i++) next[cnt][i] = -1;
     54         End[cnt++] = 0;
     55         return cnt - 1;
     56     }
     57 
     58     void init() {
     59         cnt = 0;
     60         root = newnode();
     61     }
     62 
     63     void insert(char buf[], int id) {
     64         int len = strlen(buf);
     65         int now = root;
     66         for (int i = 0; i < len; i++) {
     67             if (next[now][buf[i] - 'a'] == -1) next[now][buf[i] - 'a'] = newnode();
     68             now = next[now][buf[i] - 'a'];
     69         }
     70         End[now] += id;
     71     }
     72 
     73     void build() {
     74         queue<int> Q;
     75         fail[root] = root;
     76         for (int i = 0; i < 26; i++)
     77             if (next[root][i] == -1) next[root][i] = root;
     78             else {
     79                 fail[next[root][i]] = root;
     80                 Q.push(next[root][i]);
     81             }
     82         while (!Q.empty()) {
     83             int now = Q.front();
     84             Q.pop();
     85             End[now] += End[fail[now]];
     86             for (int i = 0; i < 26; i++)
     87                 if (next[now][i] == -1) next[now][i] = next[fail[now]][i];
     88                 else {
     89                     fail[next[now][i]] = next[fail[now]][i];
     90                     Q.push(next[now][i]);
     91                 }
     92         }
     93     }
     94 
     95     void debug() {
     96         for (int i = 0; i < cnt; i++) {
     97             printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]);
     98             for (int j = 0; j < 26; j++) printf("%2d", next[i][j]);
     99             printf("]
    ");
    100         }
    101     }
    102 } ac;
    103 
    104 int dp[55][1010];
    105 string path[55][1010];
    106 
    107 int main() {
    108   // FIN;
    109     int T;
    110     sf(T);
    111     while (T--) {
    112         sff(n, m);
    113         for (int i = 0; i < m; ++i) scanf("%s", str[i]);
    114         for (int i = 0; i < m; i++) sf(cost[i]);
    115         ac.init();
    116         for (int i = 0; i < m; ++i) ac.insert(str[i], cost[i]);
    117         ac.build();
    118         mem(dp, -1);
    119         for (int i = 0; i <= n; i++)
    120             for (int j = 0; j < ac.cnt; j++)
    121                 path[i][j] = "";
    122         int ans = 0, num1 = 0, num2 = 0;
    123         dp[0][0] = 0;
    124         for (int i = 0; i < n; ++i) {
    125             for (int j = 0; j < ac.cnt; ++j) {
    126                 if (dp[i][j] == -1) continue;
    127                 for (int k = 0; k < 26; ++k) {
    128                     int idx = ac.next[j][k];
    129                     if (dp[i + 1][idx] < dp[i][j] + ac.End[idx]) {
    130                         dp[i + 1][idx] = dp[i][j] + ac.End[idx];
    131                         path[i + 1][idx] = path[i][j] + char(k + 'a');
    132                     } else if (dp[i + 1][idx] == dp[i][j] + ac.End[idx] &&
    133                                path[i + 1][idx] > path[i][j] + char(k + 'a')) {
    134                         //fuck(path[i][j]);
    135                         path[i + 1][idx] = path[i][j] + char(k + 'a');
    136                       //  fuck(path[i][j]);
    137 
    138                     }
    139                 }
    140             }
    141         }
    142         for (int i = 1; i <= n; i++) {
    143             for (int j = 0; j < ac.cnt; ++j) {
    144                 if (ans < dp[i][j]) {
    145                     ans = dp[i][j], num1 = i, num2 = j;
    146                 } else if (ans == dp[i][j]&&path[num1][num2] > path[i][j] && path[num1][num2].size()>=path[i][j].size()) {
    147                     num1 = i, num2 = j;
    148                 }
    149             }
    150         }
    151 //        printf("%d
    ", ans);
    152         cout << path[num1][num2] << endl;
    153     }
    154     return 0;
    155 }
    View Code
  • 相关阅读:
    题解-Quantifier Question
    题解-[WC2011]最大XOR和路径
    笔记-Recursive Queries
    树套树
    SG函数
    题解-Magic Ship
    分块
    文章根据时间段显示的微信名和微信号
    jquery 在页面上根据ID定位(jQuery锚点跳转及相关操作) 经典
    nginx配置反向代理
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/11379243.html
Copyright © 2020-2023  润新知