HDU 2296
来源:互联网 发布:软件时间限制工具 编辑:程序博客网 时间:2024/06/07 00:36
思路:
开个结构体,dp[i][j]记录从i号节点开始走j步能得到的最大的权值,以及走到最大权值的方案,还有答案,每次枚举能走到的所有点,更新答案,如果答案一样就选择字典序小的一个。也可以只记录走到该节点的父亲节点,这样每次答案一样时选字典小的就通过不断回退来确定。
#include <iostream>#include <cstdio>#include <map>#include <cstring>#include <string>#include <queue>#define M 110#define N 60using namespace std;int n, m, val[M];char pat[M][15];class DPNode{public: int val; string str;};DPNode dp[M*11][N];class Node{public: int endCnt, next[30], fail, val; Node() {} void clr() { endCnt = 0; memset(next, 0, sizeof next); fail = 0; val = -1; }};Node node[M*11];class Trie{public: int root, cnt; int newNode() { node[++cnt].clr(); return cnt; } void init() { cnt = 0; root = newNode(); } void ins(char pat[], int len, int val) { int p = root; for(int i = 0; i < len; i++) { int cur = pat[i]-'a'; if(!node[p].next[cur]) node[p].next[cur] = newNode(); p = node[p].next[cur]; } node[p].endCnt++; node[p].val = val; } void build() { queue<int> q; q.push(root); while(!q.empty()) { int cur = q.front(); q.pop(); for(int i = 0; i < 26; i++) { int nxt = node[cur].next[i]; if(nxt) { int p = node[cur].fail; for(; p && node[p].next[i] == 0; p = node[p].fail); p = p ? node[p].next[i] : root; node[nxt].fail = p; q.push(nxt); } } } } int cmp(string a, string b) { for(int i = a.length()-1; i >= 0; i--) { if(a[i] != b[i]) return a[i] < b[i]; } return 0; } void solve() { for(int i = 1; i <= cnt; i++) { for(int j = 0; j <= n; j++) { dp[i][j].val = 0; dp[i][j].str = ""; } } for(int i = 1; i <= cnt; i++) { if(node[i].endCnt > 0) dp[i][0].val = node[i].val; } for(int i = 1; i <= n; i++) { for(int j = 1; j <= cnt; j++) { for(int k = 0; k < 26; k++) { int p; if(node[j].next[k]) { p = node[j].next[k]; } else { p = node[j].fail; for(; p && node[p].next[k] == 0; p = node[p].fail); p = p ? node[p].next[k] : root; } if(dp[p][i-1].val > dp[j][i].val) { dp[j][i].val = dp[p][i-1].val; dp[j][i].str = dp[p][i-1].str+(char)(k+'a'); } else if(dp[p][i-1].val == dp[j][i].val) { string temp = dp[p][i-1].str+(char)(k+'a'); if(dp[j][i].str == "" || cmp(temp, dp[j][i].str)) { dp[j][i].str = temp; } } } if(node[j].endCnt > 0) dp[j][i].val += node[j].val; } } int maxv = dp[root][n].val; string ans = ""; for(int i = n; i >= 0; i--) { if(dp[root][i].val < maxv) break; ans = dp[root][i].str; } int lenans = ans.length(); for(int i = 0; i < lenans/2; i++) swap(ans[i], ans[lenans-1-i]); //cout << "val: " << dp[root][n].val << endl;; cout << ans << endl; }};Trie trie;int main(){//freopen("C:\\Users\\zfh\\Desktop\\in.txt", "r", stdin); int t; scanf("%d", &t); while(t--) { trie.init(); scanf("%d%d", &n, &m); for(int i = 0; i < m; i++) { scanf(" %s", pat[i]); } for(int i = 0; i < m; i++) { scanf("%d", &val[i]); } for(int i = 0; i < m; i++) { trie.ins(pat[i], strlen(pat[i]), val[i]); } trie.build(); trie.solve(); } return 0;}
0 0
- HDU 2296
- HDU 2296
- HDU 2296
- hdu 2296 Ring
- Ring hdu 2296
- HDU 2296 Ring
- HDU 2296Ring
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- hdu5325 Crazy Bobo
- Dijkstra算法求最短路径(java)
- SOCKET 编程TCP/IP、UDP
- Android应用程序用户界面(五)
- jquery中 val()操作 与 复选框、下拉列表、单选按钮的设置
- HDU 2296
- 解决 build_native.py 出现CCLuaBridge.o错误
- 多张图片并列显示的问题
- 称砝码 动态规划 华为OJ
- Linux系统管理-(2)--磁盘的挂载与卸载
- android imageLoader 使用缓存策略
- Flume - 重新编译源码
- 关于实例化,以及面向对象new 与不new的区别
- android的广播事件