hdu4117.GRE Words
来源:互联网 发布:免费镜像软件 编辑:程序博客网 时间:2024/05/11 01:05
http://acm.hdu.edu.cn/showproblem.php?pid=4117
题意,给一组固定顺序的字符串,每个字符串有一个价值,现在要你去除一些字符串,使得(1)剩下的字符串序列满足相邻的两个前一个是后一个的字串;(2)满足(1)的情况下剩下的字符串的价值和最大。
先说明一下:hdu的数据有可能含有非小写字母字符……
思路,把字符串做个自动机和按顺序合成一个大串,那么大串的每一点都对应自动机上的一个点,然后dp:dp[i][x]表示到大串的第i个字符,自动机上的第x的节点的最大价值,则dp[i][x] = max(dp[j1][x], dp[j2][fa[x]], dp[j3][fail[x]], ...) + val[i]就是说有点像在自动机上面dp,不过dp的顺序是按照大串的顺序。fa[x] 是自动机上x的入节点,fail[x]是x的失败指针指向的节点,要一值往前扫到0节点。val[i]是第i个点的价值,如果这个点某个小串的结尾,则这个点的价值就是小串的价值,否则是0。因为从i可以得出唯一的x,所以这个dp其实是一维,建议用x,因为转移时可以直接确定fa[x]等节点。理论时间复杂度为O(M^2), M是大串长度,但是如果加个判断如果fail[x] == fa[x], 不必往前扫,时间复杂都可以降到O(M^1.5).
交到hdu上面的结果很诡异:
// hdu4117. GRE Words - TRIE + dp#include <map>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define sqr(x) ((x) * (x))#define two(x) (1 << (x))#define X first#define Y secondtypedef long long LL;const int MAXN = 300010;const double eps = 1e-9;const int INF = 1000000000;struct NODE{map<char, int> s;int pre, fa;char c;} trie[MAXN];int n, m, tn, head, tail, ans, tch;int val[MAXN], node[MAXN], que[MAXN], f[MAXN];void build(int x, int fa, char c){trie[x].s.clear();trie[x].pre = -1;trie[x].fa = fa;trie[x].c = c;if (fa != -1)trie[fa].s[c] = x;}void insert(char str[]){int x = 0;for (int i = 0; str[i]; ++i){char c = str[i];if (trie[x].s.find(c) == trie[x].s.end())build(tn++, x, c);node[m + i] = x = trie[x].s[c];}}void bfs(){que[head = 0] = 0;tail = 1;while (head < tail){int x = que[head], c = trie[x].c;if (x == 0) trie[x].pre = -1;else{int y = trie[trie[x].fa].pre;while (y != -1 && trie[y].s.find(c) == trie[y].s.end()) y = trie[y].pre;trie[x].pre = (y == -1)? 0: trie[y].s[c];}for (map<char, int>::iterator i = trie[x].s.begin(); i != trie[x].s.end(); ++i){que[tail++] = i->second;}++head;}}void init(){char str[MAXN];m = 0;memset(val, 0, sizeof(val));build(0, -1, -1);tn = 1;scanf("%d", &n);for (int i = 0; i < n; ++i){int pts, l;scanf("%s%d", str, &pts); l = strlen(str);val[m + l - 1] = pts;insert(str);m += l;}bfs();}void work(){ans = 0;memset(f, 0, sizeof(f));for (int i = 0; i < m; ++i){int x = node[i];f[x] = max(f[x], max(f[x], f[trie[x].fa]) + val[i]);for (int p = trie[x].pre; p != -1 && trie[p].fa != trie[p].pre; p = trie[p].pre) //优化的地方f[x] = max(f[x], f[p] + val[i]);ans = max(ans, f[x]);}}int main(){int T, ca = 0;scanf("%d", &T);while (T--){init();work();printf("Case #%d: %d\n", ++ca, ans);} return 0;}
- hdu4117.GRE Words
- HDU4117-GRE Words(AC自动机+DFS序+区间修改线段树)
- GRE Words
- GRE English Words
- 【Hdu 4117】GRE Words
- hdu4787 GRE Words Revenge
- HDU 4787 GRE Words Revenge
- HDU 4787GRE Words Revenge
- HDU 4787 GRE Words Revenge AC自动机
- HDU4787--GRE Words Revenge(在线AC自动机)
- 【AC自动机】 HDOJ 4117 GRE Words
- hdu 4787 GRE Words Revenge(AC自动机)
- [The 2011 ACM-ICPC ACRC]G.GRE Words
- hdu 4117 GRE Words (AC自动机+线段树)
- hdu 4787 GRE Words Revenge (在线AC自动机)
- hdu 4117 GRE Words 11年成都现场赛
- hdu 4117 GRE Words (ac自动机 线段树 dp)
- hdu 4787 GRE Words Revenge(分块+AC自动机)
- CWinThread线程派生类MFC多线程框架
- 如何改变Android tab 的高度和字体大小
- 无线图像(视频)传输系统ARM9+Atmega16+OV7620+nrf24l01
- 关于数据库导入中的 要求输入"&"后的参数问题
- 8脚单片机
- hdu4117.GRE Words
- Win7下VS2008编译SGDT
- 转载——数据库建立表空间 和用户 的 命令 多个数据文件
- 将pyside项目打包成windows,ubuntu和mac可执行文件。
- 第四章 初始化与清除
- 电脑防火墙打不开怎么办
- 开发笔记
- Flex4.5+Eclipse+blazeds+tomact+JDK集成
- [Javascript][jQuery]图片预加载与可变参数函数