首页 > 代码库 > HNU 13108 Just Another Knapsack Problem DP + Trie树优化

HNU 13108 Just Another Knapsack Problem DP + Trie树优化

题意:

  给你一个文本串,和一些模式串,每个模式串都有一个价值,让你选一些模式串来组成文本串,使获得的价值最大。每个模式串不止能用一次。

思路:

  多重背包,枚举文本串的每个位置和模式串,把该模式串拼接在当前位置,看下一个位置是否能得到更优值。但是,存在很多模式串不能拼在当前位置的,无效状态。所以可以用Trie树来优化转移。

代码:

  

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <string>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <functional>#include <cctype>#include <time.h>using namespace std;const int INF = 1<<30;const int MAXN = 1e5+5;const int MAXLEN = 333;const int MAXNODE = 1e5+5;;struct Trie {    int ch[MAXNODE][26];    int val[MAXNODE], use;    inline void init() {        for (int i = 0; i < 26; i++) ch[0][i] = 0;        val[0] = 0;        use = 1;    }    inline int New() {        for (int i = 0; i < 26; i++) ch[use][i] = 0;        val[use] = 0;        return use++;    }    inline int idx(char c) {        return c - a;    }    void insert(char str[], int v) {        int len = strlen(str);        int p = 0;        for (int i = 0; i < len; i++) {            int c = idx(str[i]);            if (!ch[p][c]) ch[p][c] = New();            p = ch[p][c];        }        val[p] = max(val[p], v);    }    int solve(char S[], int dp[]) {        int len = strlen(S);        for (int i = 0; i <= len; i++) dp[i] = -1;        dp[0] = 0;        for (int i = 0; i < len; i++) {            if (dp[i]<0) continue;            for (int j = i, p = 0; j <= len; j++) {                int c = idx(S[j]);                if (val[p]) dp[j] = max(dp[j], dp[i]+val[p]);                p = ch[p][c];                if (p==0) break;            }        }        return max(dp[len], 0);    }};Trie solver;char S[MAXN], P[MAXLEN];int dp[MAXN];int m, v;int main() {    #ifdef Phantom01        freopen("HNU13108.txt", "r", stdin);    #endif //Phantom01    while (scanf("%s", S)!=EOF) {        scanf("%d", &m);        solver.init();        for (int i = 0; i < m; i++) {            scanf("%s%d", P, &v);            solver.insert(P, v);        }        printf("%d\n", solver.solve(S, dp));    }    return 0;}
View Code

 

HNU 13108 Just Another Knapsack Problem DP + Trie树优化